Timeline默认的Track和Clip如下。
如果想让Timeline驱动游戏逻辑,需要自定义TrackAsset,PlayableBehaviour和PlayableAsset 来实现。目前有3种方式使用自定义功能。
Playable track ClipBehaviour TrackBehaviour
这个方法受限制严重,不推荐使用。
[TrackClipType(typeof(TextTLAsset))]
[TrackBindingType(typeof(Text))]
public class TextTLTrack : TrackAsset
{
/// <summary>
/// TrackAsset在创建时必然会遍历所有的Clip,有机会给所有的clip传值
/// </summary>
/// <param name="graph"></param>
/// <param name="gameObject"></param>
/// <param name="clip"></param>
/// <returns></returns>
protected override Playable CreatePlayable(PlayableGraph graph, GameObject gameObject, TimelineClip clip)
{
PlayableDirector direct = graph.GetResolver() as PlayableDirector;
//在Clip创建时传参
TextTLAsset asset = clip.asset as TextTLAsset;
asset.Label = direct.GetComponent<CutScenePlayer>().label;
return base.CreatePlayable(graph, gameObject, clip);
}
}
TrackAsset实现CreatePlayable方法,这条Track上每一个Clip(拖拽一个Asset就有一个Clip)都会调用一次这个方法。利用这个方法给Asset传参数。这里传递了label这个控件。
[System.Serializable]
public class TextTLAsset : PlayableAsset
{
public Text Label { set; get; }
public string Content;
/// <summary>
/// 在创建时向Behaviour传引用
/// </summary>
/// <param name="graph"></param>
/// <param name="go"></param>
/// <returns></returns>
public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
{
//创建ClipBehaviour
var playable = ScriptPlayable<TextTLBehaviour>.Create(graph);
var behaviour = playable.GetBehaviour();
behaviour.Label = Label;
behaviour.Content = Content;
return playable;
}
}
PlayableAsset实现CreatePlayable方法,并Create一个PlayableBehaviour,这个Behaviour的生命周期是绑定这个Asset的。也就是说有多个Clip就有多少Behaviour实例,所以称之为ClipBehaviour。Asset向自己的Behaviour传参Label控件和Content参数。
[Serializable]
// A behaviour that is attached to a playable
public class TextTLBehaviour : PlayableBehaviour
{
public Text Label;
public string Content;
public override void OnBehaviourPlay(Playable playable, FrameData info)
{
if (Label != null)
{
Label.text = Content;
}
}
public override void OnBehaviourPause(Playable playable, FrameData info)
{
if (Label != null)
{
Label.text = string.Empty;
}
}
}
Behaviour实现OnBehaviourPlay和OnBeahviourPause两个方法,当时间线走到对应的Asset时就会调用到。 这个方案适合于做连续台词等不需要混合的需求。
TrackBehaviour方式和ClipBehaviour大部分相似,也是需要自定义的TrackAsset,PlayableBehaviour和PlayableAsset。区别在于PlayableBehaviour由TrackAsset创建而不是Asset。
[TrackClipType(typeof(ColorTLAsset))]
[TrackBindingType(typeof(Text))]
public class ColorTLTrack : TrackAsset
{
public ScriptPlayable<ColorTLBehaviour> TrackBehaviourPlayable;
private ColorTLBehaviour behaviour;
//创建Track混合器而不是Clip
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
{
//取外部引用
PlayableDirector direct = graph.GetResolver() as PlayableDirector;
Text label = direct.GetComponent<CutScenePlayer>().label;
//创建TrackBehaviour并设置inputCount,inputCount就是Clip的个数
TrackBehaviourPlayable = ScriptPlayable<ColorTLBehaviour>.Create(graph);
TrackBehaviourPlayable.SetInputCount(inputCount);
behaviour = TrackBehaviourPlayable.GetBehaviour();
//传递参数
behaviour.label = label;
behaviour.track = this;
return TrackBehaviourPlayable;
}
}
注意,TrackBehaviour是TrackAsset创建,生命周期绑定到了TrackAsset上,当Track启动、结束后触发Behaviour的OnBehaviourPlay和OnBeahviourPause,这个Behaviour和Clip是没有关系的。
[System.Serializable]
public class ColorTLAsset : PlayableAsset
{
public Color CurColor;
public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
{
return Playable.Create(graph);
}
}
TrackBehaviour方案的Asset比较简单,只是暴露参数用于设置就好了。
public class ColorTLBehaviour : PlayableBehaviour
{
public Text label;
public ColorTLTrack track;
//OnBehaviourPlay和OnBehaviourPause方法和Clip没关系了,所以只能在ProcessFrame(Update)中获取
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
//取ClipCount
int clipCount = playable.GetInputCount();
int index = 0;
for (int i = 0; i < clipCount; i++)
{
float weight = playable.GetInputWeight(i);
//Weight > 0f的Clip是进入了的Clip,可能有多个
if (weight > 0f)
{
index = i;
break;
}
}
//根据Clip的Index取Clip和Asset
ColorTLAsset curAsset = null;
foreach (var itr in track.GetClips())
{
if (index == 0)
{
curAsset = itr.asset as ColorTLAsset;
}
index--;
}
//赋值
if (label != null)
{
label.color = curAsset.CurColor;
}
}
}
该方法适合自动控制有融合的多个Clip之间的混合。Timeline混合Demo
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。