自定义轨道需要创建以下资产
TrackAsset/PlayableAsset/PlayableBehaviour
1.TrackAsset
可创建CustomTrack继承自TrackAsset, 之后就可以在Timeline编辑界面创建CustomTrack轨道
在定义CustomTrack时,相关特性(Attribute)需要关注
[TrackClipType(typeof(XXXAsset))] 表示其轨道上可以添加什么类型的Asset
[TrackBindingType(typeof(Transform/GameObject/Animator))] 表示其轨道上可以绑定什么样的游戏节点(比如AnimationTrack绑的是Animator)
可单独创建自定义轨道(无对应的自定义PlayableAsset/PlayableBehaviour), 比如只需要绑定节点的情况

2.PlayableAsset
可创建CustomPlayableAsset继承自PlayableAsset,并定义相关可序列化的属性
在Timeline编辑界面设置后,运行时可透传至PlayableBehaviour
public class CustomPlayableAsset : PlayableAsset { public string beginMark = string.Empty; public string endMark = string.Empty; public string jumpMark = string.Empty; public override Playable CreatePlayable(PlayableGraph graph, GameObject owner) { var playable = ScriptPlayable<CustomPlayableBehaviour>.Create(graph); var pb = playable.GetBehaviour(); pb.PD = owner.GetComponent<PlayableDirector>(); pb.beginMark = beginMark; pb.endMark = endMark; pb.jumpMark = jumpMark; return playable; } }

3.PlayableBehaviour
可创建CustomPlayableBehaviour继承自PlayableBehaviour,运行时获取到jumpMark等属性,并在播放至该帧时获取信息执行逻辑
public class CustomPlayableBehaviour : PlayableBehaviour { public string beginMark = string.Empty; public string endMark = string.Empty; public string jumpMark = string.Empty; public PlayableDirector PD { get; internal set; } public override void OnBehaviourPlay(Playable playable, FrameData info) { if (PD != null && PD.playableGraph.IsValid()) { if (!string.IsNullOrEmpty(jumpMark)) { } // jump to jumpMark } } }
4.创建、获取Group信息
Timeline编辑界面可以按如下操作创建组,并重命名

运行时可以获取组信息
PlayableDirector director = xxx; TrackAsset track; foreach (var output in director.playableAsset.outputs) { // 将输出转换为TrackAsset track = output.sourceObject as TrackAsset; if (track != null) { var group = track.GetGroup(); if (group != null && group.name == "XXX") { }//TODO } }
5.运行时获取、重置轨道绑定信息
以CustomTrack为例
定义时其头部标记了特性
[TrackBindingType(typeof(Transform))]
因此运行时可以获取该轨道上绑定的Transform
PlayableDirector director = xxx; CustomTrack track = xxx;// 可以从director.playableAsset.outputs的sourceObject里找到Track Transform parent = director.GetGenericBinding(track) as Transform;
// 重置绑定
director.SetGenericBinding(track, newTransform);
还可以替换动画剪辑
AnimationTrack track = xxx; // 重新绑定AnimationClip var clips = track.GetClips(); foreach (var clip in clips) { AnimationPlayableAsset asset = clip.asset as AnimationPlayableAsset; if (asset != null) asset.clip = newClip;// 可通过原 clip.displayName 找到要替换的clip }
从Animator里根据动画剪辑名找clip
RuntimeAnimatorController controller = animator.runtimeAnimatorController; foreach (AnimationClip c in controller.animationClips) { if (c.name == clipName) //TODO }
6.根据CustomTrack实现自定义播控逻辑
public static void PlayTimeline(PlayableDirector director, string aniName) { double timeToJump = -1; CustomTrack ctrlTrack = null; foreach (var output in director.playableAsset.outputs) { // 将输出转换为TrackAsset ctrlTrack = output.sourceObject as CustomTrack; if (ctrlTrack != null) { var clips = ctrlTrack.GetClips(); foreach (var clip in clips) { CustomPlayableAsset asset = clip.asset as CustomPlayableAsset; if (asset != null && asset.beginMark == aniName) { timeToJump = (float)clip.start; break; } } break; } } if (timeToJump >= 0) { director.time = timeToJump; director.Play(); } }
注:绑定信息不保存在timeline资源里,轨道上的帧信息会保存在timeline资源里
浙公网安备 33010602011771号