How to use UTimelineComponent.SetTimelinePostUpdateFunc

Hi all,

I can’t find any documentation on the use of the UTimelineComponent function SetTimelinePostUpdateFunc.

Could anyone help me? I haven’t really done a lot with delegates in C++ (other than exposing events to BP, which works just fine).

I just want the Update event and Finish event from the Timeline so I can use them in my cpp files the way you can use a Timeline in blueprint!

My .h file has something like:

UCLASS(BlueprintType, meta = (BlueprintSpawnableComponent), ClassGroup = Managers)
class URaceRunningManager : public UActorComponent
{
	GENERATED_BODY()

	FOnTimelineEvent UpdateDelegate;

public:
	UFUNCTION(BlueprintCallable, Category = "Race Running Manager")
		void StartRace();

	void TimelineUpdateCallback(float UpdateValue);
}

My .cpp has something like:

void URaceRunningManager::StartRace()
{
	RunningRace = true;

	float FinishTime = 10.f;
	
	UTimelineComponent* Timeline = Racer->TimelineComponent;

	Timeline->SetPlayRate(1 / FinishTime);

	UpdateDelegate.BindUFunction(this, "TimelineUpdateCallback");

	Timeline->SetTimelinePostUpdateFunc(UpdateDelegate);
	Timeline->PlayFromStart();

}


void URaceRunningManager::TimelineUpdateCallback(float UpdateValue)
{
	// BREAKPOINT ON NEXT LINE, NEVER GETS TRIGGERED
	int thing = RacerManager->Racers[0]->SlotID;
	if (thing == 4)
		RacerManager->Racers[0]->SlotID = 4;
		return;
}

Note that earlier the TimelineComponent was filled with the following (where Curve is set in editor and appears to be put on the Racer correctly):

		FOnTimelineFloat TimelineCallbackFunc;
		TimelineCallbackFunc.BindUFunction(RacerManager, "TimelineCallback");

		UTimelineComponent* TimelineComponent = Racer->TimelineComponent;

		TimelineComponent->AddInterpFloat(Curve, TimelineCallbackFunc, FName("Percentage_Complete"));

The RacerManager.TimelineCallback never gets called either… (I assume it’s meant to at the end of the timeline completion? Or on the start of the timeline running? No documentation either…)

Ultimately, what I am trying to do is get an actor with a timeline to move along a spline on another (dummy) actor at the rate determined by the timeline. Is this possible?

Edit:

Today I am diving into source code, looking at [AddInterpVector][1] → [TickComponent][2] → [TickTimeline][3] which calls [SetPlaybackPosition(NewPosition, true);][4]

[The function signature for which is][5]:

/** Jump to a position in the timeline. If bFireEvents is true, event functions will fire, otherwise will not. */
	ENGINE_API void SetPlaybackPosition(float NewPosition, bool bFireEvents, bool bFireUpdate = true);

Therefore bFireUpdate should be true on TimelineTick (on TickComponent after calling Play) and we should reach [this block of code][6]:

	if (bFireUpdate)
	{
		TimelinePostUpdateFunc.ExecuteIfBound();
	}

Leading me to believe that either I am using this incorrectly or… I have no idea. I am now going to try and use a BlueprintAssignable FOnTimelineEvent UPROPERTY and see if that works! (looking at learning how to use this properly with [this tutorial][7] which may be out of date…

Edit 2:

I have tried the following, as you can see it is not useful… (You cannot use BlueprintImplementableEvent or BlueprintCallable with non MULTICAST delegates…)

Racer.h
UPROPERTY(BlueprintReadWrite, Category = “Spline Racer”)
FOnTimelineEvent TimelineEventEvent;

	UPROPERTY(BlueprintReadOnly, Category = "Spline Racer")
		FOnTimelineFloat TimelineFloatEvent;

On assigning the curve:

		TimelineComponent->AddInterpFloat(Curve, Racer->TimelineFloatEvent, FName("Percentage_Complete"));

In Race Running Manager:

		Timeline->SetTimelinePostUpdateFunc(Racer->TimelineEventEvent);

The results:

48886-eventissues.png

Finally got it working by

In my racer.h:

	UPROPERTY(BlueprintReadWrite, Category = "Spline Racer")
		FOnTimelineEvent TimelineEventEvent;

	UPROPERTY(BlueprintReadOnly, Category = "Spline Racer")
		FOnTimelineFloat TimelineFloatEvent;

	UFUNCTION(BlueprintNativeEvent, Category = "Spline Racer")
	void OnEventEvent();

	UFUNCTION(BlueprintNativeEvent, Category = "Spline Racer")
	void OnFloatEvent(float UpdatedValue);

In my constructor:

	TimelineEventEvent.BindDynamic(this, &ASplineRacer::OnEventEvent);
	TimelineFloatEvent.BindDynamic(this, &ASplineRacer::OnFloatEvent);

Lower in my cpp:

void ASplineRacer::OnEventEvent_Implementation()
{
	// print("Event Event");

	 //Do nothing!
}

void ASplineRacer::OnFloatEvent_Implementation(float UpdatedValue)
{
	// print("Float Event" + FString::SanitizeFloat(UpdatedValue));

	// Base movement code here!
}

Other things included:

Setting up the Curve:

		TimelineComponent->AddInterpFloat(Curve, Racer->TimelineFloatEvent, FName("Percentage_Complete"));

Setting the PostUpdatefunc:
UTimelineComponent* Timeline = Racer->TimelineComponent;

		Timeline->SetTimelinePostUpdateFunc(Racer->TimelineEventEvent);
1 Like