当前位置:   article > 正文

UE5 C++(十六)— Timeline的使用_ue5 c++ 轨迹

ue5 c++ 轨迹

介绍

这里有官方文档介绍比较详细,我这边简单描述,重在实践。

时间轴(Timeline)可以实现从事件中播放基于时间的动画,这些事件可以沿着时间轴在关键帧处触发。可以使用时间轴来处理简单的非动画任务,例如开门、更改光源或对场景中的Actor执行其他以时间为中心的操纵。

关键组件:UTimelineComponent
包含一系列的 事件(events)、 浮点数(floats)、向量(vectors) 或 颜色(colors) 及其关联的关键帧。这些内容继承自UActorComponents

创建Timeline时间轴

在蓝图中创建

在这里插入图片描述
双击后可以添加浮点曲线等
在这里插入图片描述

在C++中创建

创建一个继承于Actor的C++类 MyTimelineActor,在这个类里写Timeline相关逻辑。在这里插入图片描述
MyTimelineActor.h

#pragma once

#include "CoreMinimal.h"
#include "Components/TimelineComponent.h"
#include "GameFramework/Actor.h"
#include "MyTimelineActor.generated.h"

UCLASS()
class DEMO_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 = "MyCurve")
	UCurveFloat *MyCurveFloat;
	// 时间轴组件
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MySceneComponent")
	UTimelineComponent *MyTimeline;

	// 声明时间轴回调函数
	FOnTimelineFloat TimelineCallback;
	// 声明时间轴结束事件  时间轴事件(FOnTimelineEvent)是动态委托,为时间轴组件提供处理事件的能力
	FOnTimelineEvent TimelineFinishedCallback;

	// 时间轴开始函数
	UFUNCTION(BlueprintCallable, Category = "MyTimeline")
	void TimelineStart(float Value);
	// 时间轴结束函数
	UFUNCTION(BlueprintCallable, Category = "MyTimeline")
	void TimelineFinished();
};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

MyTimelineActor.cpp


#include "MyTimelineActor.h"

// Sets default values
AMyTimelineActor::AMyTimelineActor()
{
	// 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;

	MyTimeline = CreateDefaultSubobject<UTimelineComponent>(TEXT("MyTimeline"));

}

// Called when the game starts or when spawned
void AMyTimelineActor::BeginPlay()
{
	Super::BeginPlay();

	TimelineCallback.BindUFunction(this, FName("TimelineStart"));
	TimelineFinishedCallback.BindUFunction(this, FName("TimelineFinished"));
	// 绑定时间轴曲线
	MyTimeline->AddInterpFloat(MyCurveFloat, TimelineCallback);
	// 
	MyTimeline->SetLooping(false);
	MyTimeline->PlayFromStart();
	MyTimeline->Play();
	MyTimeline->SetTimelineFinishedFunc(TimelineFinishedCallback);
}

// Called every frame
void AMyTimelineActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

void AMyTimelineActor::TimelineStart(float Value)
{
	UE_LOG(LogTemp, Warning, TEXT("TimelineStart"));
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("TimelineStart")));
}
void AMyTimelineActor::TimelineFinished()
{
	UE_LOG(LogTemp, Warning, TEXT("TimelineFinished"));
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("TimelineFinished")));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

编译之后,创建浮点曲线
在这里插入图片描述
这里添加的浮点曲线,相当于蓝图中添加的浮点曲线
在这里插入图片描述
右键,添加关键帧
在这里插入图片描述
保存之后,创建MyTimelineActor的蓝图类
在这里插入图片描述
添加刚才创建的浮点曲线
在这里插入图片描述
编译,保存之后,拖到场景中运行,打印日志
在这里插入图片描述

在这里插入图片描述

使用Timeline实现开关门

拷贝引用 门模型:/Script/Engine.StaticMesh’/Game/StarterContent/Architecture/Wall_400x400.Wall_400x400’
在这里插入图片描述
MyTimelineActor.h


#pragma once

#include "CoreMinimal.h"
#include "Components/TimelineComponent.h"
// 引入组件
#include "Components/SceneComponent.h"
#include "Components/StaticMeshComponent.h"
#include "Components/BoxComponent.h"
#include "MyCharacter.h"
#include "GameFramework/Actor.h"
#include "MyTimelineActor.generated.h"

UCLASS()
class DEMO_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 = "MyCurve")
	UCurveFloat *MyCurveFloat;
	// 时间轴组件
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyScene")
	UTimelineComponent *MyTimeline;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyScene")
	USceneComponent *MyScene;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyScene")
	UStaticMeshComponent *MyStaticMesh;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyScene")
	UBoxComponent *MyBox;

	//声明绑定碰撞函数
	UFUNCTION()
	void BeginOverlapFunction(UPrimitiveComponent *OverlappedComponent, AActor *OtherActor, UPrimitiveComponent *OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult);
	UFUNCTION()
	void EndOverlapFunction(UPrimitiveComponent *OverlappedComponent, AActor *OtherActor, UPrimitiveComponent *OtherComp, int32 OtherBodyIndex);

	// 声明时间轴回调函数
	FOnTimelineFloat TimelineCallback;
	// 声明时间轴结束事件  时间轴事件(FOnTimelineEvent)是动态委托,为时间轴组件提供处理事件的能力
	FOnTimelineEvent TimelineFinishedCallback;

	// 时间轴开始函数
	UFUNCTION(BlueprintCallable, Category = "MyTimeline")
	void TimelineStart(float Value);
	// 时间轴结束函数
	UFUNCTION(BlueprintCallable, Category = "MyTimeline")
	void TimelineFinished();

	
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

MyTimelineActor.h

// Fill out your copyright notice in the Description page of Project Settings.

#include "MyTimelineActor.h"

// Sets default values
AMyTimelineActor::AMyTimelineActor()
{
	// 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;

	MyTimeline = CreateDefaultSubobject<UTimelineComponent>(TEXT("MyTimeline"));
	MyScene = CreateDefaultSubobject<USceneComponent>(TEXT("MyScene"));
	MyStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticMesh"));
	MyBox = CreateDefaultSubobject<UBoxComponent>(TEXT("MyBox"));
	RootComponent = MyScene;
	MyStaticMesh->SetupAttachment(MyScene);
	MyBox->SetupAttachment(MyScene);
	MyBox->SetRelativeLocation(FVector(200.f, 0.f, 0.f));
	MyBox->SetBoxExtent(FVector(200.f, 80.f, 100.f));

	// note: 这段代码会导致UE5崩溃,原因未知 所以静态Mesh我在蓝图手动添加
	//  	// 添加门的模型
	//  	static ConstructorHelpers::FObjectFinder<UStaticMesh> TempStaticMesh(TEXT("/Script/Engine.StaticMesh'/Game/StarterContent/Architecture/Wall_400x400.Wall_400x400'"));
	//  	if (TempStaticMesh.Succeeded())
	//  	{
	//  		MyStaticMesh->SetStaticMesh(TempStaticMesh.Object);
	//  	}
}

// Called when the game starts or when spawned
void AMyTimelineActor::BeginPlay()
{
	Super::BeginPlay();

	TimelineCallback.BindUFunction(this, FName("TimelineStart"));
	TimelineFinishedCallback.BindUFunction(this, FName("TimelineFinished"));
	// 绑定时间轴曲线
	MyTimeline->AddInterpFloat(MyCurveFloat, TimelineCallback);
	//
	// MyTimeline->SetLooping(false);
	// MyTimeline->PlayFromStart();
	// MyTimeline->Play();
	MyTimeline->SetTimelineFinishedFunc(TimelineFinishedCallback);

	MyBox->OnComponentBeginOverlap.AddDynamic(this, &AMyTimelineActor::BeginOverlapFunction);
	MyBox->OnComponentEndOverlap.AddDynamic(this, &AMyTimelineActor::EndOverlapFunction);
}

// Called every frame
void AMyTimelineActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

void AMyTimelineActor::TimelineStart(float Value)
{
	UE_LOG(LogTemp, Warning, TEXT("TimelineStart"));
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("TimelineStart")));
	// 旋转门 动画
	float YawRotation = FMath::Lerp(0.f, 90.f, Value);
	MyStaticMesh->SetRelativeRotation(FRotator(0.f, YawRotation, 0.f));
}
void AMyTimelineActor::TimelineFinished()
{
	UE_LOG(LogTemp, Warning, TEXT("TimelineFinished"));
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("TimelineFinished")));
}

void AMyTimelineActor::BeginOverlapFunction(UPrimitiveComponent *OverlappedComponent, AActor *OtherActor, UPrimitiveComponent *OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult)
{
	AMyCharacter *MyCharacter = Cast<AMyCharacter>(OtherActor);
	UE_LOG(LogTemp, Warning, TEXT("BeginOverlapFunction"));
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("BeginOverlapFunction")));
	if (MyCharacter)
	{
		MyTimeline->PlayFromStart();
	}
}
void AMyTimelineActor::EndOverlapFunction(UPrimitiveComponent *OverlappedComponent, AActor *OtherActor, UPrimitiveComponent *OtherComp, int32 OtherBodyIndex)
{
	AMyCharacter *MyCharacter = Cast<AMyCharacter>(OtherActor);
	if (MyCharacter)
	{
		MyTimeline->ReverseFromEnd();
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87

编译之后,打开蓝图BP_MyTimelineActor ,调整一下
在这里插入图片描述
在这里插入图片描述
然后拖到场景中,摆放一下位置
在这里插入图片描述
点击运行,人物接触时门自动打开
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/107122
推荐阅读
相关标签
  

闽ICP备14008679号