What is the proper way to use timelines from code?

To learn more about the engine, I have been trying to recreate in code the fireball actor from the FeaturesTour2014.
You can find a quick example of the actor in this video (~4min): https://youtu.be/MkhHix5g1m0?t=249

For the last 3 days, I have been struggling on how to implement the timeline used in the blueprint.
Here is the timeline in the BP:

And here is the float curve contained in the timeline:

Here is the corresponding code I came up with.

Inside the code of my fireball actor, I create a curve object based on the curve file.

static ConstructorHelpers::FObjectFinder<UCurveFloat> CurveTest(TEXT("CurveFloat'/Game/Scale.Scale'"));
Curve = CurveTest.Object;

Then I create the test timeline and attach it an event for the update, an event for the end, and an event to the curve update. Each function consists of a simple log print.

	FTimeline test;
	test.SetTimelineLength(1);
	FOnTimelineEvent testEvent = FOnTimelineEvent();
	testEvent.BindDynamic(this, &AFireBall::OnEventEvent);

	FOnTimelineEvent testEvent2 = FOnTimelineEvent();
	testEvent2.BindDynamic(this, &AFireBall::OnEventEvent2);

	FOnTimelineFloat testEvent3 = FOnTimelineFloat();
	testEvent3.BindUFunction(this, "ProgessTimeLine");

	test.AddInterpFloat(Curve, testEvent3, FName("Percentage_Complete"));
	
	test.SetTimelineFinishedFunc(testEvent);
	test.SetTimelinePostUpdateFunc(testEvent2);
	UE_LOG(FantasiaInit, Log, TEXT("Start test."));

	test.PlayFromStart();

Now here is the result:

FantasiaInit: Start test.

FantasiaInit: ProgessTimeLine 1.000000

FantasiaInit: OnEventEvent2

But if I run the timeline used in the example fireball blueprint, the update function is being called dozens of times.
Do you have any idea on what is the difference?

1 Like

As usual, just after posting the question, you find the answer… :slight_smile:

So for everyone asking themselves the same question, the implementation was ok.
There was just one thing to add to the code, the TickTimeline in the tick of the actor.

void AFireBall::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

	test.TickTimeline(DeltaTime); // That was the line needed! 

}

As a complement to your answer, you can also use Timelines WITHOUT having to call them in the Tick.
Heres a very easy how to do.

!Note: On UE4.14 I couldnt seem to find the FOnTimeline.BindDynamic method, instead, I used the FOnTimeline.BindUFunction(this, FName{TEXT(“FunctionNameHere”)}) described in the linked post and works wonders.