? ????在蓝图中可以很容易的创建一个时间轴,如图1.1.1所示为一个新建的时间轴,双击时间轴可以添加不同的轨道,分别有浮点、向量和事件,具体的可以自己去玩玩,这个在虚幻的开发中是非常常用的,最后创建的时间轴要绑定到一个事件中触发。
在C++代码中也会经常用到时间轴,本案例中将通过时间轴创建一个开关门的效果。
? ? ? ? 本系列使用的虚幻5.2.1,VS2022。
1、创建一个新的类命名为“MyTimelineActor”,添加头文件然后创建时间轴变量,代码如下:
#include "TimerManager.h"//定时器头文件
//定时器变量
FTimerHandle Time;
void PrintTime();
并创建一个后面要用到的回调打印函数。
2、然后在类的开始事件中使用,代码如下,这样就可以得到一个简单的定时器函数:每隔1秒执行“PrintTime"函数。
void AMyTimelineActor::BeginPlay()
{
Super::BeginPlay();
//每个固定秒打印,最后两个参数分别为间隔事件和是否循环
GetWorld()->GetTimerManager().SetTimer(Time, this, &AMyTimelineActor::PrintTime, 1.0f, true);
}
//实现打印函数
void AMyTimelineActor::PrintTime()
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Green, TEXT("Time"));
}
3、清除定时器
? ? ? ? 清除的代码如下,可以在任何触发后的函数中执行如下代码,之后上述的定时器即可停止。
清除时间
if (Time.IsValid())
{
GetWorld()->GetTimerManager().ClearTimer(Time);
}
1、需要添加头文件,通过蓝图的时间轴我们可以明白,时间轴中最重要的是曲线也即图1.1.1中创建的轨道,这里要先定义这个变量,然后再在创建的蓝图中绑定曲线,另外我们还需要创建一个门,所以还需要一个静态网格的变量,最后还有开始和结束的处理函数,完整的代码如下
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyCharacter1.h"
#include "Components//BoxComponent.h"
#include "Components/TimelineComponent.h"
#include "MyTimelineActor.generated.h"
UCLASS()
class CHAPTER2_API AMyTimelineActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMyTimelineActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Timeline")
UCurveFloat* CurveFloat;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Timeline")
UTimelineComponent* Timeline;
FOnTimelineFloat TimelineDelegate;//一开始的绑定
FOnTimelineEvent FinishedDelagate;//完成时的绑定
UFUNCTION()
void TimelineStart(float valuee);
UFUNCTION()
void TimelineFinished();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Timeline")
USceneComponent* Scene;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Timeline")
UStaticMeshComponent* StaticMesh;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Timeline")
UBoxComponent* Box;
}
2、在CPP文件中先添加网格组件,然后设置开始方法和结束方法的逻辑分别对应开关门,也即旋转门到一定角度,代码如下
void AMyTimelineActor::TimelineStart(float valuee)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Green, FString::Printf(TEXT("Timeline Play:%f"), valuee));
//旋转,绕着固定轴插值旋转
float tempYawRot = FMath::Lerp(0, 90, valuee);
StaticMesh->SetRelativeRotation(FRotator(0, tempYawRot, 0));
}
void AMyTimelineActor::TimelineFinished()
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("Timeline Finished"));
}
3、在整个类的开始事件中绑定上述两个方法并执行时间轴的运行方法,设置是否循环,代码如下。
void AMyTimelineActor::BeginPlay()
{
Super::BeginPlay();
TimelineDelegate.BindUFunction(this, TEXT("TimelineStart"));
FinishedDelagate.BindUFunction(this, TEXT("TimelineFinished"));
//设置浮点曲线
Timeline->AddInterpFloat(CurveFloat, TimelineDelegate);
Timeline->SetLooping(true);
Timeline->PlayFromStart();
Timeline->Play();
Timeline->SetTimelineFinishedFunc(FinishedDelagate);
}
4、编译成功后创建一个上述类的蓝图“BP_TimelineActor”,然后创建一个浮点曲线”TimelineCurve“,如图2.2.1所示,
在浮点曲线中添加两个关键帧分别为(0,0)和(1,1),然后将这个新建的”浮点曲线“拖动到”BP_TimelineActor“蓝图中的曲线变量里,如图2.2.2所示
注:如果没有这个变量运行的时候会导致崩溃。
5、这样得到的效果如图2.2.3所示,门会循环往复的开关,图中每次都是从起始位置重新打开,如
果要实现关闭的效果要用到方法,这个函数的意思是从结束的地方反着再执行一边。
Timeline->ReverseFromEnd();//从后面往前播放
3.1、简单的事件定时器可以绑定执行中的函数,而时间轴可以绑定开始和结束的函数。
3.2、简单定时器需要代码中清除,否则会一直执行,时间轴设置好时间曲线里的时间,在该时间内执行完会自动关闭,除非设置了循环。
3.3、时间轴可以通过反向执行函数实现一些特有的反方向操作,比如关门等。
3.4、?? ?UCurveFloat* CurveFloat;是一个变量,定义了后一定要在后续的蓝图中绑定曲线蓝图,否则会直接崩溃。