首页 > 编程语言 >UE4_C++实现TimeLine

UE4_C++实现TimeLine

时间:2023-11-23 16:11:46浏览次数:54  
标签:曲线 VecEntry 委托 TimeLine 绑定 C++ CWTimeline 时间轴 UE4

主要实现蓝图节点中时间轴的功能。
image
目前UE提供了两种实现方式,一个是使用FTimeLine其是一个时间轴的结构体;另一种方式是使用UTimeLineComponent,其是一个时间轴组件类。两者内部定义的函数基本一样,组件类中使用这个结构体变量作为类中的成员变量。
image

声明一个时间轴变量/组件

FTimeLine结构体和UTimeLineComponent组件都存在于TimelineComponent.这个类里面所以需要

#include "Components/TimelineComponent.h"

参考1

  1. 利用UTimeLineComponent
    时间轴是利用委托绑定函数来实现在时间轴的范围内,实现动画切换或者其他功能的。
    所以我们一般需要定义两个委托事件,分别处理时间轴每帧的操作和时间轴结束的操作。UE定义了4种绑定事件委托的类型(也对应有静态委托)
    image
    一般绑定事件使用FOnTimelineEvent,当如果我们想使用曲线或者向量来控制时间轴的变化我们需要使用对应的下面3个委托。这3个委托会返回对应曲线的每一帧的位置数值。
    image
    如果利用C++编写就需要在UE中新建曲线,然后在使用时间轴的Actor类中,定义一个曲线变量用来接受设置的曲线,并且将该变量传入对应的动态委托中。
    image
    image
//.h

//设置一个时间轴组件变量
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly)
UTimelineComponent*  CWTimeline;
//设置一个曲线
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly)
UCurveFloat* CWFloatCurve;

//设置委托事件
//定义曲线更新事件,事件定义的选择要和我们使用的曲线选择对应
	FOnTimelineFloat OnCWTimelineTickCallBack;
//定义曲线播发完成事件
	FOnTimelineEvent OnCWTimelineFinishedCallBack;

//设置委托绑定的函数
UFUNCTION()
	void CWTimelineTickCallBack(float value);
UFUNCTION()
	void CWTimelineFinishedCallBack();

接下来就需要开始定义和初始化这些声明设置。在BeginPlay()中进行委托的绑定和组件的初始化操作。(不知道在构造函数位置是否可以)
由于我们使用的组件,所以需要实例化来获取里面结构体,就如同相机组件或者弹簧臂组件一样。这是第一个与FTimeLine不同的地方。

CWTimeline = NewObject<UTimelineComponent>(this,"CrouchTimeLine");
//NewObject CreateDefaultObject的区别还不太明白。。。。。。

然后就直接开始委托绑定

OnCWTimelineTickCallBack.BindDynamic(this,&ClassName::CWTimelineTickCallBack)
//我们要把这个委托附加给时间轴,然后我们是根据曲线来进行时间轴的输出,我们利用委托可以获得曲线的每一帧的数值,然后传给被绑定的函数
CWTimeline->AddInterpFloat(CWFloatCurve,OnCWTimelineTickCallBack)

//当时间轴事件结束的委托
OnCWTimelineFinishedCallBack.BindDynamic(this, &AJCharacter:CWTimelineFinishedCallBack);
CWTimeline->SetTimelineFinishedFunc(OnCWTimelineFinishedCallBack);

//注册组件
CWTimeline->RegisterComponent();

在委托所绑定的函数上进行我们要进行的操作,比如将摄像机的位置发生变化
其中利用插值函数实现平滑的过渡
value的实参是通过委托获取曲线的每一帧数值。

void AJCharacter::CWTimelineTickCallBack(float value)
{
	SpringArmComp->SocketOffset.X = 0.0f;
	SpringArmComp->SocketOffset.Y = SpringArmComp->SocketOffset.Y;
	SpringArmComp->SocketOffset.Z = FMath::Lerp(0.0f, -40.0f,value);
}

void AJCharacter::CWTimelineFinishedCallBack()
{
}

最后我们可以在想要使用时间轴的函数中进行播放时间轴,比如在下蹲时摄像头的变化

void AJCharacter::JCrouch()
{
	if (!GetCharacterMovement()->IsCrouching()) {
		Crouch();
		bIsCrouch = true;
		GetCharacterMovement()->MaxWalkSpeedCrouched = 135.0f;
		CWTimeline->Play();
	}
	else {
		UnCrouch();
		bIsCrouch = false;
		GetCharacterMovement()->MaxWalkSpeed = 420.0f;
		CWTimeline->Reverse();
	}
	
}

利用CWTimeline->Play()和CWTimeline->Reverse()实现正向和反向的播放。

注意:我们必须在Tick()函数中设置时间轴的TickComponent才能进行时间轴的播放

CWTimeline->TickComponent(DeltaTime, ELevelTick::LEVELTICK_TimeOnly, NULL);
  1. 利用FTimeLine结构体
    参考2

  2. FOnTimelineFloat委托

DECLARE_DYNAMIC_DELEGATE_OneParam( FOnTimelineFloat, float, Output );

通过定义可以看出,该委托有一个float类型的输出,该输出可以直接使用于该委托绑定的函数。
而这个值就是通过我们设置的CurveFloat插值得到的。
我们利用AddInetrpFloat(CurveFloat,FOnTimelineFloat)后,实际将CurveFloat做为其中一个参数传入到了元素类型为FTimelineFloatTrack的一个数组中。
image
而时间轴的更新是通过其里面的FTimeline::SetPlaybackPosition方法。

	/** Jump to a position in the timeline. 
	  * @param bFireEvents If true, event functions that are between current position and new playback position will fire. 
	  * @param bFireUpdate If true, the update output exec will fire after setting the new playback position.
	 */
	UFUNCTION(BlueprintCallable, Category="Components|Timeline", meta=(AdvancedDisplay="bFireUpdate"))
	ENGINE_API void SetPlaybackPosition(float NewPosition, bool bFireEvents, bool bFireUpdate = true);

通过VecEntry.InterpFunc.ExecuteIfBound(Vec);将当前位置值传递出去,

FTimelineVectorTrack& VecEntry = InterpVectors[InterpIdx];
		if ( VecEntry.VectorCurve && (VecEntry.InterpFunc.IsBound() || VecEntry.VectorPropertyName != NAME_None || VecEntry.InterpFuncStatic.IsBound()) )
		{
			// Get vector from curve
			FVector const Vec = VecEntry.VectorCurve->GetVectorValue(Position);

			// Pass vec to specified function
			VecEntry.InterpFunc.ExecuteIfBound(Vec);
            //VecEntry.InterpFunc获取委托

通过AddInetrpFloat后我们得到的一个结构体变量,InterpFunc就是里面的委托,用来传递代码中委托时间的float值

	/** Function that the output from ValueCurve will be passed to */
	UPROPERTY()
	FOnTimelineFloat InterpFunc;

ExecuteIfBound为单播委托的调用方式,输出Vec,使得绑定函数可以使用。参考
image

  1. Play()和Reverse()
void FTimeline::Play()
{
	bReversePlayback = false;//true
	bPlaying = true;
}

调用之后,因为我们在Tick()使用了TickComponent,其将调用TickTimeLine
image
设置bPlaying为true后将调用SetPlaybackPosition方法,根据DeltaTime返回Position的值,从而获取曲线的对应值。从而得到输出

标签:曲线,VecEntry,委托,TimeLine,绑定,C++,CWTimeline,时间轴,UE4
From: https://www.cnblogs.com/XTG111/p/17851332.html

相关文章

  • C++程序编译常见错误与评测各个状态含义
    编译常见错误提示1.[Error]expected';'before'cout'。在cout前面,缺少一个分号。2.[Error]'b'wasnotdeclaredinthisscope。未定义变量名b。3.[Error]stray'\243'inprogram\stray'\273'inprogram。不可识别的非法字符。4.[Error]ldretu......
  • 引发C++异常的常见原因(一)从报错地址到错误症状
    在进行C++软件开发的过程中,会遇到很多问题,网上差不到,或者查到了也没什么信息可以用,所以这里想到了就将一些常见的问题放在一起,归纳整理一下。本文主要的内容来源于CSDN的大佬文章:https://blog.csdn.net/chenlycly/article/details/125529931,我主要是做个笔记常见问题1.变量未......
  • C++11线程传递参数汇总
    一、概述总结C++11线程传递参数:1.传递基本数据类型(int、double)2.传递字符串3.传递结构体4.传递类对象二、代码示例//导入线程头文件#include<thread>//导入std命名空间usingnamespacestd;//传递int类型的参数voidthreadFu......
  • c++小程序/随机产生100以内的一个自然数,给出7次机会猜测数的大小
    一、随机产生100以内的一个自然数,给出7次机会猜测数的大小要求:1、 如果猜对了,提示:“真聪明,您猜对了!”,并退出程序2、 如果猜得数比随机数大,给出提示“你猜的数太大了”3、 如果猜得数比随机数小,提示“您猜的数太小了”,如果超出七次没有猜对,提示“很遗憾,您没有猜对”,并退出程序......
  • c++小程序/类Date
    声明类Date要求:1、使用户可以设置日期,并在输入错误时提示。a一年12个月,若输入12以外的数,提示“输入月份错误”b每个月依次有{31,28/29,31,30,31,30,31,31,30,31,30,31}若输入的数值超过该月天数,提示“输入天数错误”。2、可以查询两个日期之间相差天数注意:闰年Code#include<iostr......
  • c++小程序/数组排序
    数组排序1、定义交换两个整型数的函数swap2、定义sort函数给数组排序,调用swap函数Code#include<iostream.h>template<classT>voidswap(T&x,T&y){Ttemp;temp=x;x=y;y=temp;}template<classp>voidsort(p*a,pb){for(inti=0;i<10;i++){......
  • c++小程序/输入三个数,判断能不能组成三角形
    输入三个数,判断能不能组成三角形要求:1、输入-1,0,-1,提示“你输入的为负数”2、输入1,2,3,提示“你输入的三个数不能组成三角形”3、输入3,4,5提示“输入的三个数能组成三角形,并且是一个直角三角形”4、输入3,3,4提示“输入的三个数能组成三角形,并且是一个等腰三角形”1、 输入3,3,3提示“输......
  • c++(4)
    C++(4)1.C++模板1.1模板的概论C++提供了函数模板(functiontemplate),函数模板是将函数的参数类型不具体化,在函数使用时,再给定具体的参数的数据类型。C++给定两个模板机制:函数模板和类模板【注】都属于参数类型的模板,又称之为参数模板1.2函数模板函数模板可以自动推......
  • C/C++ 开发SCM服务管理组件
    SCM(ServiceControlManager)服务管理器是Windows操作系统中的一个关键组件,负责管理系统服务的启动、停止和配置。服务是一种在后台运行的应用程序,可以在系统启动时自动启动,也可以由用户或其他应用程序手动启动。本篇文章中,我们将通过使用Windows的服务管理器(SCM)提供的API接口,......
  • wxwidgets实战手册-c++(2)
    目录oninitoninit继承自wxApp的子类,可将它视为main和winmain,应用程序的入口//wxWidgets"HelloWorld"Program//Forcompilersthatsupportprecompilation,includes"wx/wx.h".#include<wx/wxprec.h>#ifndefWX_PRECOMP#include<wx/wx.h>......