首先,一个Timeline是由多个track组成。每个track又是又多个clip组成。如下图所示。这是一个动画的track。在后面,放着的idle、walk等都是一个个的动画clip。随着时间的进行,后面这些动画clip都会使用到挂在的物体上,让他做出这一个个动作。
除了track、clip之外,上图中还有behaviour。正如名字一样,他是定义行为、掌管逻辑的东西。每一个clip都有其自己的行为。比如动画clip就可以将动画的数据作用到对应的物体上,声音clip就可以控制系统中的声音,Cinemachine clip就可以控制摄像机一样,每一个clip都会跟着一个behaviour来定义其行为。
同上,上面还有一个MixerBehaviour。他定义的是两个clip片段之间的融合过度如何处理。Timeline中一个很重要的功能就是过度,上图中walk和jump两个clip就有一部分重合在了一起,当时间运行到这一部分的时候,这两个动画该怎么样同时应用到一个物体上就需要MixerBehaviour脚本来定义。
好了,做一个总结。一套完整的Timeline拓展需要自定义track、clip、clip的behaviour、MixerBehaviour。
其中Track脚本继承自TrackAsset,Clip脚本继承自PlayableAsset和ITimelineClipAsset,clip的行为脚本继承自PlayableBehaviour,MixerBehaviour也继承自PlayableBehaviour。
先做一个普通的clip,他可以直接放在Timeline内置的playable轨道。
using System;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
[Serializable]
public class SimpleClip : PlayableAsset, ITimelineClipAsset
{
public SimpleBehaviour template = new SimpleBehaviour ();
//这个函数是将Clip与Behaviour绑定的必要函数。
public override Playable CreatePlayable (PlayableGraph graph, GameObject owner)
{
var playable = ScriptPlayable.Create(graph, template);
return playable;
}
//定义clip的特性,比如blending, extrapolation, looping, etc.。是对ITimelineClipAsset接口的实现。
public ClipCaps clipCaps
{
get { return ClipCaps.None; }
}
}
其中有一个定义行为的SimpleBehaviour。
using System;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
[Serializable]
public class SimpleBehaviour : PlayableBehaviour
{
public string message;
//Timeline运行到这个Clip时,每帧都会回调的函数
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
//里面就写每帧的逻辑
Debug.Log(message);
}
}
这样,就定义了一个Clip,他每帧就会在控制台发送一个Log。
在Timeline的Playable轨道上就可以创建这个SimpleClip
以下的说法都是我自己的理解,不一定全正确。
Timeline是基于Unity中Playable这个类进行拓展的。这个类的拥有数据,然后调用Unity中别的系统,以使数据的效果得以发挥。在Untiy中使用Playable进行拓展的另个例子就是Animator动画系统。Timeline就像是一个打杂糅,他可以调用动画系统、摄像机、音频系统、后处理、Active等,并且如何有额外的需要,我们还可以自己写脚本,关联其他的系统。通常,他关联什么系统,看Timeline的轨道就可以理解。
第二张图里面,Default Playable是在unity商店中免费下载的Timeline拓展。他额外拓展了几个轨道和Clip。里面有代码示例。
OnBehaviourDelay //在 Playable 播放状态更改为 PlayState.Delayed 时调用此函数。
OnBehaviourPause //出现以下某种情况之一时,将调用此方法: 遍历期间的有效播放状态更改为
PlayState.Paused。此状态由 FrameData.effectivePlayState 指示。 在可播放项播放状态为 Playing 时停止 PlayableGraph。此状态由 PlayableGraph.IsPlaying 返回的 true 结果指示。
OnBehaviourPlay //在 Playable 播放状态更改为 PlayState.Playing 时调用此函数。
OnGraphStart //在拥有此 PlayableBehaviour 的 PlayableGraph 启动时调用此函数。当该图开始播放时或首次调用 PlayableGraph.Evaluate 时,系统会调用 OnGraphStart。每次调用 OnGraphStart 都会同时调用 OnGraphStop。
OnGraphStop //在拥有此 PlayableBehaviour 的 PlayableGraph 停止时调用此函数。
OnPlayableCreate //在拥有 PlayableBehaviour 的 Playable 创建后调用此函数。
OnPlayableDestroy //在拥有 PlayableBehaviour 的 Playable 销毁后调用此函数。
PrepareData //在 PlayableGraph 的 PrepareData 阶段调用此函数。只要可播放项延迟,系统就会调用 PrepareData。
PrepareFrame //在 PlayableGraph 的 PrepareFrame 阶段调用此函数。应使用 PrepareFrame 进行拓扑修改、更改连接权重、更改时间等。
ProcessFrame //在 PlayableGraph 的 ProcessFrame 阶段调用此函数。ProcessFrame 是您的可播放项执行其任务的阶段。当可播放项播放并且直接或间接连接到 ScriptPlayableOutput 时,为每个帧调用此方法。
Destroy | 销毁当前 Playable。 |
GetDelay | 返回可播放项的延时。 |
GetDuration | 返回 Playable 的持续时间。 |
GetGraph | 返回拥有此 Playable 的 PlayableGraph。Playable 只能在用于创建它的图中使用。 |
GetPlayState | 返回 Playable 的当前播放状态。 |
GetSpeed | 返回应用于当前 Playable 的速度乘数。 |
GetTime | 返回 Playable 的当前本地时间。 |
IsDelayed | 返回指示 Playable 是否存在延迟的值。 |
IsDone | 返回指示可播放项已完成操作的标志。 |
IsNull | 如果 Playable 为 null,则返回 true,否则返回 false。 |
IsValid | 返回当前 Playable 的有效性。 |
Pause | 发出暂停 Playable 的通知。 |
Play | 开始播放 Playable。 |
SetDelay | 设置可播放项开始播放之前的延时。 |
SetDone | 更改指示可播放项已完成操作的标志。 |
SetDuration | 更改 Playable 的持续时间。 |
SetInputCount | 更改 Playable 支持的输入数量。 |
SetInputWeight | 更改连接到当前 Playable 的 Playable 的权重。 |
SetLeadTime | 设置 Playable 前置时间(以秒为单位)。 |
SetOutputCount | 更改 Playable 支持的输出数量。 |
SetPropagateSetTime | 更改此 Playable 的时间传播行为。 |
SetSpeed | 更改应用于当前 Playable 的速度乘数。 |
SetTime | 更改 Playable 的当前本地时间。 |
SetTraversalMode | 设置多输出可播放项的 PrepareFrame 和 ProcessFrame 传播模式。 |
struct in UnityEngine.Playables
描述
此结构包含 Playable 在 Playable.PrepareFrame 中收到的帧信息。
变量
deltaTime | 该帧与上一帧之间的时间差。 |
effectiveParentDelay | PlayableGraph 遍历期间,父 Playable 的累积延迟。 |
effectiveParentSpeed | PlayableGraph 遍历期间,父 Playable 的累积速度。 |
effectiveSpeed | PlayableGraph 遍历期间,Playable 的累积速度。 |
effectiveWeight | PlayableGraph 遍历期间,Playable 的累积权重。 |
evaluationType | 指示导致调用 PlayableGraph.PrepareFrame 的评估类型。 |
frameId | 当前帧标识符。 |
output | 发起此图遍历的 PlayableOutput。 |
seekOccurred | 指示本地时间为显式设置。 |
timeHeld | 指示本地时间未推进,因为它已到达持续时间且外推模式设置为 Hold。 |
timeLooped | 指示本地时间已循环,因为它已到达持续时间且外推模式设置为 Loop。 |
weight | 当前 Playable 的权重。 |