Variables Timers Events _implementation function not working

Hi,

I’m following the Variables, Timers & Events tutorial

I’ve gone through pages 1-3 and everything works great, except that calling CountdownHasFinished() isn’t resulting in CountdownHasFinished_Implementation() being called.

This results in the text being displayed reaching 0, and remaining on 0 forever, instead of being changed to “Go!”

I’ve looked over numerous related forum posts and answers, but can’t see any similar issues with the answers I need (apologies if I’ve missed one).

header:

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/TextRenderComponent.h"
#include "Engine/EngineTypes.h"
#include "Countdown.generated.h"

UCLASS()
class EVENTSLEARNING_API ACountdown : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ACountdown();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// How long, in seconds, the timer countdown will run for
	UPROPERTY(EditAnywhere)
	int32 CountdownTimeStartingValue;
	
	int32 CountdownTime;

	UTextRenderComponent* CountdownText;
	
	// Replaces text in world with text displaying correct time
	void UpdateTimerDisplay();

	// Ticks the timer down every second
	void AdvanceTimer();

	// Performed when countdown timer has finished
	UFUNCTION(BlueprintNativeEvent)
	void CountdownHasFinished();
	virtual void CountdownHasFinished_Implementation();

	FTimerHandle CountdownTimerHandle;
};

code:

// Fill out your copyright notice in the Description page of Project Settings.

#include "Countdown.h"
#include "Components/TextRenderComponent.h"
#include "Engine/EngineTypes.h"
#include "Engine/World.h"

// Sets default values
ACountdown::ACountdown()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	CountdownText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("CountdownNumber"));
	CountdownText->SetHorizontalAlignment(EHTA_Center);
	CountdownText->SetWorldSize(150.0f);
	RootComponent = CountdownText;

	CountdownTime = 3;
}

// Called when the game starts or when spawned
void ACountdown::BeginPlay()
{
	Super::BeginPlay();
	
	CountdownTime = CountdownTimeStartingValue;

	UpdateTimerDisplay();
	GetWorldTimerManager().SetTimer(CountdownTimerHandle, this, &ACountdown::AdvanceTimer, 1.0f, true);
}

// Called every frame
void ACountdown::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

void ACountdown::UpdateTimerDisplay()
{
	CountdownText->SetText(FString::FromInt(FMath::Max(CountdownTime, 0)));
}

void ACountdown::AdvanceTimer()
{
	--CountdownTime;
	UpdateTimerDisplay();

	if (CountdownTime < 1)
	{
		// Clean up the time handle and stop the timer
		GetWorldTimerManager().ClearTimer(CountdownTimerHandle);
		CountdownHasFinished();
		GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, TEXT("Function called"));
	}
}

void ACountdown::CountdownHasFinished_Implementation()
{
	// Change to a special readout
	CountdownText->SetText(TEXT("GO!"));
	GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, TEXT("Implementation Function called"));
}

Many thanks :slight_smile:

… I was rushing through the tutorial at the end of my lunch. It covers the answer by showing you how to call the original “parent” function in blue print.

I am an idiot - sorry!