UE4中的时间管理

发表于2016-06-18
评论0 1.28w浏览
  游戏逻辑中难免会遇到一些时间相关的功能需求,UE4也提供了一些时间相关的功能。
  当前UE4版本4.11.1。

一、时间轴
  TimeLine是方便的用于时间相关变量控制的地方,在蓝图编辑器中可以创建时间轴。
  双击相关时间轴可以进入编辑模式。
  Timeline的编辑与大部分的曲线编辑器类似,[官方文档]的描述也非常的详尽。大部分与时间变化有关的功能都可以使用Timeline来实现。
  Timeline也可以与Interp系列函数配合来实现动态的值域调整。


  在时间轴相关函数中,还有两个比较特殊的函数。
  分别是SetPlayRate。


  用于设置时间轴播放的速率,以及SetTimeLineLengthMode。


  这个函数的功能似乎与官方的描述有些不同,只会影响到SetTimeLineLength的效果,而不会对实际播放产生影响。
  不知道是设计如此还是文档描述上的问题。
  查看Timeline.cpp中的源码可以看到LengthMode这个变量并没有在TickTimeline()函数中使用。
  在整个引擎中只在Timeline本身的函数GetTimelineLength与SetTimelineLengthMode中被使用到。


  引擎源码中的注释为

1
2
3
/** Specified how the timeline determines its own length (e.g. specified length, last keyframe) */
UPROPERTY(NotReplicated)
TEnumAsByte LengthMode;

  从这里看,应该是文档的描述方式有问题。这个变量是不会对播放模式进行影响的。

二、Matinee
  对于关卡中的物体控制,UE4提供了一套更加方便的工具,那就是Matinee。
  毕竟,如果要用Timeline来对物体进行控制,无论在实现还是管理上都非常的麻烦。
  Matinee可以用于关卡中物品的移动控制,如电梯。也可以用于摄像头的控制来实现漫游展示,或者是过场动画。
  Matinee的使用相当的简单明了,如果之前有使用过类似的动画制作软件的话,会很容易上手。
  通过[官方文档]能快速上手,其中有不少例程可以作为参考。

三、速度控制
  UE4中有一套自己的时间控制系统,可以实现类似于子弹时间、固有时制御的功能。
  要对整个游戏时间的运行速率进行控制,可以使用SetGlobalTimeDilation。


  设置的值在0.0001与20之间,超过范围会被Clamp。也就是说可以减慢10000倍或者加速20倍。
  不建议加速太多,对运算效率的消耗非常大。玩家的配置不够时会出现问题。
  另外有专门对Actor用的速度控制函数:


  可以单独调整物体的时间速率。

四、定时器
  Timer用于在中指定的时间上运行特定的任务,主要用于周期性执行任务,也可以实现类似于Delay的功能。
  定时器的功能由一系列函数构成,使用起来非常直观。


  在C++中也可以对Timer进行使用,所有继承自AActor的类都可以使用GetWorldTimerManager来进行定时器设定。

1
2
3
FTimerHandle time_handler;
 
GetWorldTimerManager().SetTimer(time_handler, FTimerDelegate::CreateSP(this, &SMusicList::DelayTest), 0.3f, false);

  需要注意的是,对于有的类,直接这样使用是有风险的,需要判定一下世界是否存在。否则,在UWorld为空时会导致跳出。

1
if(GetWorld()) GetWorld()->GetTimerManager().ClearAllTimersForObject(this);

五、Tick
  Tick会在每帧都被调用,可以用于一些需要严格同步的功能。
  在UE4中,Tick函数有TickGroup的概念,各个组中的Tick中每一帧中被调用的时机是不同的。
 · TG_PrePhysics – 在物理模拟运行之前执行
 · TG_StartPhysics – 用于开始物理引擎的特殊的Tick组
 · TG_DuringPhysics – 与物理引擎并行执行的Tick组
 · TG_EndPhysics – 用于结束物理模拟的特殊的Tick组
 · TG_PostPhysics- 在刚体以及衣物的模拟结束后才会运行的Tick组
 · TG_PostUpdateWork – 在帧内所有更新完成之后才会执行的Tick组
 · TG_LastDemotable – 所有被延迟到最后执行的的Tick组
 · TG_NewlySpawned – 特殊的Tick组,实际上并不是一个组,而是在所有的Tick组都运行完毕后,对所有世界中新生成的物体进行Tick
  一般情况下Tick是隶属于TG_PrePhysics的,也有一些功能在其他的组中,例如粒子发射器就是运行在TG_PostUpdateWork组中的。Tick的调用通常来自UWorld实例的Tick函数。
  Slate中的Tick是直接来源于SWidget中的Paint函数的,因此带有额外的参数。
  通常tick的运行函数应该尽量的简单,否则有可能会导致游戏卡死。
  在蓝图中,可以对蓝图类对应的TickGroup进行修改。


  不是继承自AActor的类可能没有这个函数,因为他们可能并不属于TickGroup系统的管辖之下。控件蓝图由于是来自UUserWidget的,所以并没有这个函数。

六、总结
  UE4中目前的时间相关函数基本够用,基本上需要的逻辑都能通过上面的几个类目中的功能实现。
  时间相关的函数有时会难以调试,不过只要提前注意的话就不会有什么太大的问题,一般情况下。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引