[UE C++] Timeline
本文用开关门介绍Timeline的简单用法
1. 创建相关的StaticMesh
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
UStaticMeshComponent* Door;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
UStaticMeshComponent* DoorFrame;
构造函数:
DoorFrame = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorFrameMesh"));
Door = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorMesh"));
DoorFrame->SetupAttachment(RootComponent);
Door->AttachToComponent(DoorFrame,FAttachmentTransformRules::KeepRelativeTransform);
2. Timeline
在开始使用Timeline之前,可以思考一下下面几个问题:
- Timeline的作用是什么?在我看来就是根据 Curve 的时间(横坐标),去得到数值(纵坐标),然后将这个数值传递给程序员使用
- 那么数值是如何传递给程序员的呢?这就要提到UE C++经常要使用到的Delegate(委托)了,数值传递就是通过 Delegate 实现的
- 由上,我们可以总结出来使用Timeline的几个关键之处:Curve ,Delegate
2.1 TimelineComponent
需要#include "Components/TimelineComponent.h"
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
UTimelineComponent* DoorTimelineComp;
构造函数
DoorTimelineComp = CreateDefaultSubobject<UTimelineComponent>(TEXT("DoorTimelineComp"));
2.2 Curve
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UCurveFloat* DoorTimelineFloatCurve;
这里使用的是UCurveFloat,因为只会改变Door的Yaw。还存在 UCurveVector
, UCurveLinearColor
等
2.3 Delegate
FOnTimelineFloat DoorTimelineFloatDelegate;
因为使用的是UCurveFloat,所以需要对应类型的Delegate,还存在FOnTimelineVector
,FOnTimelineLinearColor
查看源代码可以发现,这是一组动态委托,所以Bind的函数指针需要加上UFUNCTION()
标记,不然函数无法执行
/** Signature of function to handle a timeline 'event' */
DECLARE_DYNAMIC_DELEGATE( FOnTimelineEvent );
/** Signature of function to handle timeline float track */
DECLARE_DYNAMIC_DELEGATE_OneParam( FOnTimelineFloat, float, Output );
/** Signature of function to handle timeline vector track */
DECLARE_DYNAMIC_DELEGATE_OneParam( FOnTimelineVector, FVector, Output );
/** Signature of function to handle linear color track */
DECLARE_DYNAMIC_DELEGATE_OneParam( FOnTimelineLinearColor, FLinearColor, Output );
同样还存在一组普通委托可供我们使用
/** Static version of delegate to handle a timeline 'event' */
DECLARE_DELEGATE( FOnTimelineEventStatic );
/** Static version of timeline delegate for a float track */
DECLARE_DELEGATE_OneParam( FOnTimelineFloatStatic, float );
/** Static version of timeline delegate for a vector track */
DECLARE_DELEGATE_OneParam( FOnTimelineVectorStatic, FVector );
/** Static version of timeline delegate for a linear color track */
DECLARE_DELEGATE_OneParam( FOnTimelineLinearColorStatic, FLinearColor );
关于委托的更多介绍,可以参考这篇文章UE 委托详解
有了用于传递数值的Delegate,我们就可以将自己需要执行的逻辑(函数)与之Bind
函数声明:
UFUNCTION()
void UpdateDoorRotation(float CurveOutput);
函数定义:
void ATimelineTest::UpdateDoorRotation(float CurveOutput)
{
// 基于时间轴曲线的输出创建并设置门的新相对位置
FRotator DoorNewRotation = FRotator(0.0f, CurveOutput, 0.f);
Door->SetRelativeRotation(DoorNewRotation);
}
注意事项:
- 因为使用的是动态委托,所以需要加上UFUNCTION()
- 函数的输入必须与Delegate的类型一致
函数与Delegate绑定:
这里放在BeginPlay()中进行Bind,也可以在其它地方
void ATimelineTest::BeginPlay()
{
Super::BeginPlay();
DoorTimelineFloatDelegate.BindDynamic(this, &ThisClass::UpdateDoorRotation);
}
2.4 关联
有了以上的基础之后,我们还需要将Curve,TimelineComponent,Delegate关联起来
同样放在BeginPlay()中进行:
void ATimelineTest::BeginPlay()
{
Super::BeginPlay();
DoorTimelineFloatDelegate.BindDynamic(this, &ThisClass::UpdateDoorRotation);
if (DoorTimelineFloatCurve)
{
DoorTimelineComp->AddInterpFloat(DoorTimelineFloatCurve, DoorTimelineFloatDelegate);
}
}
2.5 运行
运行Timeline的方法很简单
DoorTimelineComp->Play();
DoorTimelineComp->PlayFromStart();
DoorTimelineComp->Stop();
DoorTimelineComp->Reverse();
DoorTimelineComp->ReverseFromEnd();
UE还提供了很多相关API对Timeline进行管理,感兴趣的同学可以进源码看看
2.6 Finish Callback
这里再介绍Timeline Finished的回调方法,就是当Timeline执行完毕之后,如何执行我们的自定义事件
同样是依靠委托进行,这次我们使用静态委托:
委托定义:
FOnTimelineEventStatic onDoorTimelineFinishedCallback;
回调函数声明:
//可以不加UFUNCTION()
void DoorOpenFinish();
回调函数定义:
void ATimelineTest::DoorOpenFinish()
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, TEXT("Door Open Finish"));
}
关联和Bind
在BeginPlay()中
onDoorTimelineFinishedCallback.BindUObject(this, &ThisClass::DoorOpenFinish);
DoorTimelineComp->SetTimelineFinishedFunc(onDoorTimelineFinishedCallback);
最后:
以上就是如何用C++使用Timeline的简单介绍,后面的步骤就是在Editor中创建蓝图,曲线等操作,比较简单,相信读者有能力自我完成😁
如有错误,欢迎大佬指出