主要实现蓝图节点中时间轴的功能。



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

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

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

#include "Components/TimelineComponent.h"

参考1

  1. 利用UTimeLineComponent

    时间轴是利用委托绑定函数来实现在时间轴的范围内,实现动画切换或者其他功能的。

    所以我们一般需要定义两个委托事件,分别处理时间轴每帧的操作和时间轴结束的操作。UE定义了4种绑定事件委托的类型(也对应有静态委托)



    一般绑定事件使用FOnTimelineEvent,当如果我们想使用曲线或者向量来控制时间轴的变化我们需要使用对应的下面3个委托。这3个委托会返回对应曲线的每一帧的位置数值。



    如果利用C++编写就需要在UE中新建曲线,然后在使用时间轴的Actor类中,定义一个曲线变量用来接受设置的曲线,并且将该变量传入对应的动态委托中。



//.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的一个数组中。



而时间轴的更新是通过其里面的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,使得绑定函数可以使用。参考

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

调用之后,因为我们在Tick()使用了TickComponent,其将调用TickTimeLine



设置bPlaying为true后将调用SetPlaybackPosition方法,根据DeltaTime返回Position的值,从而获取曲线的对应值。从而得到输出

UE4_C++实现TimeLine的更多相关文章

  1. Chrome Developer Tools:Timeline Panel说明

    一.Timeline panel 概况 Timeline工具栏可以详细检测出Web应用在加载过程中,时间花费情况的概览.这些应用包括下载资源,处理DOM事件, 页面布局渲染或者向屏幕绘制元素. 如下图 ...

  2. Chrome 开发工具之Timeline

    之前有说到Element,Console,Sources大多运用于debug,Network可用于debug和查看性能,今天的主角Timeline更多的是用在性能优化方面,它的作用就是记录与分析应用程 ...

  3. iOS之TimeLine(时间轴)的实现

    这是一个关于OC时间轴的简单实现,我认为重要的是思路. 感谢作者:Cyandev 的文章<iOS 实现时间线列表效果>给的思路.这里先附上Objective-C的代码实现,有时间再去试试S ...

  4. 如何使用Goolge Timeline工具

    网上中文的资料版本比较老,找到一个新版本的英文介绍,翻一下,原文:https://developers.google.com/web/tools/chrome-devtools/profile/eva ...

  5. 【三石jQuery视频教程】03.创建垂直时间表(Timeline)

    视频地址:http://v.qq.com/page/g/i/o/g0150rvi6io.html 大家好,欢迎来到[三石jQuery视频教程],我是您的老朋友 - 三生石上. 今天,我们要通过基本的H ...

  6. WPF中的动画——(三)时间线(TimeLine)

    WPF中的动画——(三)时间线(TimeLine) 时间线(TimeLine)表示时间段. 它提供的属性可以让控制该时间段的长度.开始时间.重复次数.该时间段内时间进度的快慢等等.在WPF中内置了如下 ...

  7. 如何使用Chrome Timeline 工具(译)

    [原文地址]https://developers.google.com/web/tools/chrome-devtools/profile/evaluate-performance/timeline- ...

  8. 分享最新的博客到LinkedIn Timeline

    使用Octopress作为我的博客框架有两年了.使用起来一直很顺手,这个工具真正的把博客跟写代码等同起来,非常酷炫.再加上各种各样的定制化,简直是随心所欲.我针对自己的需求对Octopress框架进行 ...

  9. chrome dev debug network 的timeline说明

    在使用chrome的时候F12的开发者工具中有个network,其中对每个请求有个timeline的说明,当鼠标放上去会有下面的显示: 这里面的几个指标在说明在chrome使用文档有说明: 下面我用人 ...

  10. Chrome开发者工具详解(3)-Timeline面板

    Chrome开发者工具详解(3)-Timeline面板 注: 这一篇主要讲解面板Timeline,参考了Google的相关文档,主要用于公司内部技术分享.. Timeline面板 Timeline面板 ...

随机推荐

  1. git 添加子模块

    参考:https://www.jianshu.com/p/10ae453701ed 问题:如果一个子模块的分支不是最新的该怎么处理? 方法:在主仓库内使用 cd 命令切换到子模块的仓库,使用 git ...

  2. virtualapp安装应用流程源码分析

    1. HomeActivity 为处理的入口 @Override protected void onActivityResult(int requestCode, int resultCode, In ...

  3. PrettyTable模块

    # 用来生成美观的ASCII格式的表格 pip install prettytable # 导入 from prettytable import PrettyTable # 使用 tb = pt.Pr ...

  4. 【算法day5】排序算法的稳定性及其汇总

    稳定性 定义:值相同的元素在排序完成之后能否保证原有的次序不变(同样值的个体之间,如果不因为排序而改变相对次序,这个排序就是有稳定性的,否则就没有) 举例: [2,1,3,1]-->[1,1,2 ...

  5. ASP.NET Core MVC应用模型的构建[3]: Controller的收集

    从编程的角度来看,一个MVC应用是由一系列Controller类型构建而成的,所以对于一个代表应用模型的ApplicationModel对象来说,它的核心就是Controllers属性返回的一组Con ...

  6. 【Azure Developer】Visual Studio 2019中如何修改.Net Core应用通过IIS Express Host的应用端口(SSL/非SSL)

    问题描述 在VS 2019调试 .Net Core Web应用的时,使用IIS Express Host,默认情况下会自动生成HTTP, HTTPS的端口,在VS 2019的项目属性->Debu ...

  7. 【Azure 媒体服务】AMS的Manifest文件中SmoothStreamingMedia片段中<c t="6161940" d="749970" r="2" n="0" />, c, t, d, r, n 的解析

    问题描述 在Azure媒体服务(AMS: Azure Media Service)中,不管是点播,直播都需要下载manifest文件.而文件中有一段[<c t="6161940&quo ...

  8. linux的简单使用

    了解Linux的简单使用 Linux的安装 下载Linux Ubuntu版本和虚拟机VMware软件. 我已经提前下载好了,下载好的文件分享出来bd 这个是文件夹内的VMWare软件的注册码,安装完成 ...

  9. 5、mysql优化--索引使用情况、索引的结构

    避免索引失效 1). 全值匹配 ,对索引中所有列都指定具体值. 2). 最左前缀法则 如果索引了多列,要遵守最左前缀法则.指的是查询从索引的最左前列开始,并且不跳过索引中的列. 3). 范围查询右边的 ...

  10. (一)Git 学习之为什么要学习 Git

    一.版本控制 1.1 何为版本控制 版本控制(Revision control)是一种在开发的过程中用于管理我们对文件.目录或工程等内容的修改历史,方便查看更改历史记录.备份,以便恢复以前的版本的软件 ...