Hi,
I’d like to use Timelines, here, to continously log a float value from a UCurveFloat. I see 3 options here and would like to know, what would be the most elegant solution.
TestActor.cpp:
UCLASS()
class THETHIRDPERSONGAME_API ATestActor : public AActor
{
GENERATED_BODY()
public:
ATestActor();
virtual void Tick(float DeltaTime) override;
UPROPERTY()
UTimelineComponent* TimelineComponent;
UPROPERTY()
FTimeline Timeline;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
UCurveFloat* CurveFloat;
FOnTimelineFloat OnTimelineFloat{};
UFUNCTION()
void TimelineFloatReturn(float Value);
protected:
virtual void BeginPlay() override;
private:
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
TObjectPtr<UStaticMeshComponent> Mesh;
};
TestActor.cpp:
#include "TestActor.h"
ATestActor::ATestActor()
{
PrimaryActorTick.bCanEverTick = true;
Mesh = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
SetRootComponent(Mesh);
TimelineComponent = CreateDefaultSubobject<UTimelineComponent>("TimelineScore");
}
void ATestActor::TimelineFloatReturn(float Value)
{
UE_LOG(LogTemp, Warning, TEXT("%s - %f"), *FString(__FUNCTION__), Value);
}
A) Using FTimeline with Tick
Great, that I don’t need an ActorComponent.
Bad, that there is going to be a function call (or a condition check) for each Tick.
void ATestActor::BeginPlay()
{
Super::BeginPlay();
OnTimelineFloat.BindUFunction(this, "TimelineFloatReturn");
Timeline.AddInterpFloat(FCurve, InterpFunction, "Floaty");
Timeline.Play();
}
// Called every frame
void ATestActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
Timeline.TickTimeline(DeltaTime);
}
B) Using UTimelineComponent
Great, that Tick is kept free.
Bad, that I need an ActorComponent.
void ATestActor::BeginPlay()
{
Super::BeginPlay();
OnTimelineFloat.BindUFunction(this, "TimelineFloatReturn");
TimelineComponent->AddInterpFloat(CurveFloat, OnTimelineFloat);
TimelineComponent->Play();
}
C) Using FTimeline with SetTimer()
I actually didn’t managed to make this work but it should l look something like this. There is a thread were someone made it work (How to create a Timeline in C++?), however I can’t compile that code. Any suggestions how to make this approach work?
GetWorld()->GetTimerManager().SetTimer(CameraExtension.TimerHandle,
FTimerDelegate::CreateLambda([this(){
TimeLine.TickTimeline(GetWorld()->GetDeltaSeconds());}), 0.f, false);
I’m a bit confused why the Blueprints provide such intuitive (at least in my opinion) interface to Timelines and C++ not.
What’s the most elegant / performant solution?
Thanks in advance.