虚幻学习笔记19—C++中使用时间轴

2023-12-21 11:03:12

一、前言

? ????在蓝图中可以很容易的创建一个时间轴,如图1.1.1所示为一个新建的时间轴,双击时间轴可以添加不同的轨道,分别有浮点、向量和事件,具体的可以自己去玩玩,这个在虚幻的开发中是非常常用的,最后创建的时间轴要绑定到一个事件中触发。

图1.1.1

在C++代码中也会经常用到时间轴,本案例中将通过时间轴创建一个开关门的效果。

? ? ? ? 本系列使用的虚幻5.2.1,VS2022。

二、实现

2.1、创建一个简单的定时器

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);
	}
2.2、创建时间轴

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所示,

图2.2.1

在浮点曲线中添加两个关键帧分别为(0,0)和(1,1),然后将这个新建的”浮点曲线“拖动到”BP_TimelineActor“蓝图中的曲线变量里,如图2.2.2所示

图2.2.2

注:如果没有这个变量运行的时候会导致崩溃。

5、这样得到的效果如图2.2.3所示,门会循环往复的开关,图中每次都是从起始位置重新打开,如

图2.2.3

果要实现关闭的效果要用到方法,这个函数的意思是从结束的地方反着再执行一边。

Timeline->ReverseFromEnd();//从后面往前播放

三、总结

3.1、简单的事件定时器可以绑定执行中的函数,而时间轴可以绑定开始和结束的函数。

3.2、简单定时器需要代码中清除,否则会一直执行,时间轴设置好时间曲线里的时间,在该时间内执行完会自动关闭,除非设置了循环。

3.3、时间轴可以通过反向执行函数实现一些特有的反方向操作,比如关门等。

3.4、?? ?UCurveFloat* CurveFloat;是一个变量,定义了后一定要在后续的蓝图中绑定曲线蓝图,否则会直接崩溃。

文章来源:https://blog.csdn.net/zhangxiao13627093203/article/details/135109782
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。