Unity中的Timeline

时间:2022-11-05 11:58:32


一:前言

Timeline与动画系统类似,但是它可以针对多个物体做出一系列多个动画,它可以创建多个轨道,对象激活与隐藏轨道,动画轨道,声音轨道等。每个轨道都可以单独编辑,轨道内的不同资源可以排列并且融合


二:基础操作

可以单独Lock某一条轨道或Mute(禁用)某一条轨道


三:Activation Track(对象激活与隐藏轨道)

Unity中的Timeline


控制物体的显隐,在时间区域内是显示


四:Animation Track(动画轨道)

Unity中的Timeline


控制游戏物体的动画,与Animator一样,可以点击红点进行录制,可以控制身上任一组件的参数。在此轨道上右键可以选择Convert To Clip Track转换成动画片段,进而可以对动画进行更多的设置

Unity中的Timeline


——Start/End:开始和结束的秒数和帧数


——Duration:总持续时间的秒数和帧数


——Ease In/Out Duration:动画融合的时间


——Speed Multiplier:速度


——Pre/Post Extrapolate:开始和结束的游戏物体状态


None:动画开始前/结束后保持物体原位置不变


Hold:动画开始前/结束后保持动画开始和结束位置


Loop:动画开始前/结束后动画循环播放


PingPong:动画开始前/结束后动画来回播放


Continue:动画开始前动画播放一遍,结束后动画没变化


五:Audio Track(声音轨道)

Unity中的Timeline


 控制声音的播放


六:Signal Track(信号轨道)

Unity中的Timeline


Signal包含三部分:Signal Asset(信号资源),Signal Emitter(信号发射器)和SignalReceiver(信号接收器),它其实就是一个Event,作用就是在单独轨道上面添加事件点,在某一帧执行某个方法

——创建信号发射器和信号资源

在轨道上右键选择Add Signal Emitter,Inspector面板选择从Project面板创建的Signal Asset或Create一个新的Signal Asset

——创建信号接收器

Unity中的Timeline


添加Signal Receiver,对应的游戏物体身上会自动添加Signal Receiver组件,与UGUI绑定按钮事件相似(将物体拖拽到Timeline窗口中可以选择Add Signal Track将会自动给物体添加Signal Receiver组件) 

using UnityEngine;

public class Cube : MonoBehaviour
{
public void OnTimelineSignal()
{
Debug.Log("OnTimelineSignal");
}
}

自定义Signal

using UnityEngine;using UnityEngine.Playables;
using UnityEngine.Timeline;

public class CustomSignalReceiver : MonoBehaviour, INotificationReceiver
{
public void OnNotify(Playable origin, INotification notification, object context)
{
var signal = notification as CustomSignal;
if (signal != null
&& signal.asset != null)
{
Debug.Log(signal.param);
}
}
}

public class CustomSignal : SignalEmitter
{
public int param;
}

七: 自定义Timeline

Timeline分为以下四部分
——Track:轨道,继承自TrackAsset
——Clip:片段,一段Clip代表一个Playable,继承自PlayableAsset
——Behavior、MixerBehavior:属于行为逻辑模板,继承自PlayableBehaviour

——创建Behaviour/MixerBehavior

Unity中的Timeline


自定义行为逻辑,基类有一套自己的生命周期

OnPlayableCreate:每个Clip创建时( Playable播放状态为playing时),相当于Awake

OnGraphStart:每个Clip创建时( Playable播放状态为playing时),在OnPlayableCreate后执行,相当于Start

OnBehaviourPlay:Clip执行时

OnBehaviourPause:Clip暂停时

PrepareFrame:每帧执行,相当于Update,playerData就是轨道绑定的物体,默认是PlayableDirector组件挂载的物体

OnGraphStop:Playable停止时

OnPlayableDestroy:Playable销毁时 ————创建Clip

Unity中的Timeline


通过GetBehaviour获取到Behaviour,将逻辑和数据联系起来

可以继承ITimelineClipAsset接口去定义ClipCaps类型——创建Track

Unity中的Timeline


——TrackColor特性:控制轨道颜色

——TrackClipType特性:可以添加的Clip类型

——TrackBindingType特性:绑定的数据对象,在ProcessFrame函数中会以playerData的形式传递进去

——OnCreateClip:面板上创建Clip时

——CreateTrackMixer:创建自定义混合轨道

——GetClips:获取轨道内的所有ClipAsset


八:自定义TImeline案例——全屏遮罩

using UnityEngine;
using UnityEngine.Timeline;
using UnityEngine.Playables;
using UnityEngine.UI;

[TrackColor(1, 0, 0)]
[TrackBindingType(typeof(Image))]
[TrackClipType(typeof(ScreenFadeClip))]
public class ScreenFadeTrack : TrackAsset
{
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
{
return ScriptPlayable<ScreenFadeMixBehavioour>.Create(graph, inputCount);
}
}
using UnityEngine;
using UnityEngine.Playables;

public class ScreenFadeClip : PlayableAsset
{
public Color maskColor;

public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
{
var playable = ScriptPlayable<ScreenFadeMixBehavioour>.Create(graph);
var behaviour = playable.GetBehaviour();
behaviour.maskColor = maskColor;
return playable;
}
}
using System.Collections;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.UI;

public class ScreenFadeMixBehavioour : PlayableBehaviour
{
Image img;

public Color maskColor;

public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
Color blendColor = Color.clear;

img = playerData as Image;
if (img != null)
{
int inputCount = playable.GetInputCount();
for (int i = 0; i < inputCount; i++)
{
float tempWeight = playable.GetInputWeight(i);
ScreenFadeMixBehavioour tempBehaviour = ((ScriptPlayable<ScreenFadeMixBehavioour>)playable.GetInput(i)).GetBehaviour();
blendColor += tempBehaviour.maskColor * tempWeight;
}
img.color = blendColor;
}
}

public override void OnBehaviourPause(Playable playable, FrameData info)
{
if (img != null)
{
img.color = Color.clear;
}
}
}