I want to implement a simple function that fires a Timeline from Start > Finish, and the Float value along the Timeline is sent to another function.
I can’t find any examples anywhere of how to implement this, and the documentation isn’t helping me. The only thing I’ve found on the subject so far is this, but none of the parameters he is passing in are explained, and FOnTimelineFloat doesn’t seem to exist.
Does anybody actually have these working? Most people I’ve seen asking about this have just gone back to using FInterpTo and not using a curve.
Whats wrong with using a data curve for it? I used FloatCurve (miscellaneous->curve in the editor data type) and used that for interpolation (pass in elapsed time, get back float). Why would you need timeline, unless you want to animate other properties together with it?
How about looking at the blueprint interface for Timeline and seeing how it uses them?
Basically what I wanted to do was just tell the Timeline “Play From The Start”, with just a one-time call that would manage it.
Instead I’ve had to create a Timer that re-calls the function until the Time has elapsed, passing the time in and getting the value along the curve. Isn’t there a TimeLine manager of some kind similar to Timers that handles the playback of them?
I’m using a simeple c++ implemented timeline for a door that can be opened/closed which is based on the link u posted.
The FOnTimelineFloat is part of the engine, so should be available (FOnTimelineFloat | Unreal Engine Documentation)
Header file:
// Copyright 2015 Deborggraeve Randy. All Rights Reserved.
#pragma once
#include "Interaction/SwatUsableActor.h"
#include "SwatDoor.generated.h"
UCLASS()
class ASwatDoor : public ASwatUsableActor
{
public:
GENERATED_BODY()
public:
/* Sets default values for the properties */
ASwatDoor(const FObjectInitializer& ObjectInitializer);
/** Update the properties. */
virtual void Tick(float DeltaSeconds) override;
/** Starts interacting with the object */
virtual void StartInteract() override;
/** Returns true if the object is currently interactable */
virtual bool CanInteract() override;
/** Returns the name of the interaction */
virtual const FString GetInteractionName() override;
/** Function which gets called from the Timeline on a Tick */
UFUNCTION()
void AnimationEffectProgress(float Value);
public:
/** Timeline for the effectprogress*/
FTimeline AnimationTimeLine;
/** Rotate the door to the other side */
UPROPERTY(EditAnywhere, Category = "Animation")
bool bInverseRotation;
/** Current state of the door */
bool bIsOpen;
};
Source file:
// Copyright 2015 Deborggraeve Randy. All Rights Reserved.
#include "SwatReloaded.h"
#include "SwatDoor.h"
ASwatDoor::ASwatDoor(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
// 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;
// Setup the animation
const ConstructorHelpers::FObjectFinder<UCurveFloat> Curve(TEXT("/Game/Animations/Curves/DoorRotationCurve"));
AnimationTimeLine = FTimeline{};
FOnTimelineFloat progressFunction{};
progressFunction.BindUFunction(this, "AnimationEffectProgress");
AnimationTimeLine.AddInterpFloat(Curve.Object, progressFunction, FName{ TEXT("EFFECTFADE") });
// Set the initial state
bIsOpen = false;
}
void ASwatDoor::Tick(float DeltaSeconds)
{
if (AnimationTimeLine.IsPlaying())
{
AnimationTimeLine.TickTimeline(DeltaSeconds);
}
}
void ASwatDoor::StartInteract()
{
if (!AnimationTimeLine.IsPlaying())
{
if (bIsOpen)
{
bIsOpen = false;
AnimationTimeLine.Reverse();
}
else
{
bIsOpen = true;
AnimationTimeLine.Play();
}
}
}
bool ASwatDoor::CanInteract()
{
return bInteractable && !AnimationTimeLine.IsPlaying();
}
const FString ASwatDoor::GetInteractionName()
{
if (bIsOpen)
{
return TEXT("Close Door");
}
else
{
return TEXT("Open Door");
}
}
void ASwatDoor::AnimationEffectProgress(float Value)
{
FRotator Rotation(0.0f, bInverseRotation ? -Value : Value, 0.0f);
SetActorRelativeRotation(Rotation);
}
I have a little update on this as there is still some very old answers on answerhub which uses tick function from actor and other stuff etc. which gives some confusion about why to actually use timeline in the first place.
I hope I didnt put some wiki up with something that doesn’t drive
I just tested it again on my side on 4.10 and it the timeline flows. Where do you call Play() or PlayFromStart()? Play() activates the tick of the timeline component. U don’t need to call TickTimeline() yourself. Try to put AddInterpFloat() at Begin Play or anywhere else outside the constructor if you haven’t done so already.
I was using [FONT=Courier New]FTimeline instead of [FONT=Courier New]UTimelineComponent*
After I changed, it worked without the Tick() function.
I’m probably very tired and I ended up missing this, I’m sorry. Your guide is solid
Thank you for your guide!
Btw, if it help anyone out there, using [FONT=Courier New]UTimelineComponent* and initializing it on the constructor is enough to make it work without the tick function, apparently (I haven’t tested thoroughly, but it’s working on my setup ).