链接:https://www.jianshu.com/p/ef6510d6b516
https://www.freesion.com/article/18881359998/
自定义轨道
首先需要创建一个自定义轨道的脚本,继承TrackAsset:
using UnityEngine;
using UnityEngine.Timeline;
[TrackClipType(typeof(LightControlAsset))]
[TrackBindingType(typeof(Light))]
public class LightControlTrack : TrackAsset {}
这段代码用了两个Attribute:
TrackClipType
指定了轨道接收的PlayableAsset类型;TrackBindingType
指定了轨道要求绑定的对象类型。
现在还需要修改PlayableAsset和PlayableBehaviour,也就是之前的LightControlAsset和LightControlBehaviour。
LightControlBehaviour的代码如下:
using UnityEngine;
using UnityEngine.Playables;
public class LightControlBehaviour : PlayableBehaviour
{
//public Light light = null; 不再需要它了
public Color color = Color.white;
public float intensity = 1f;
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
Light light = playerData as Light; // 这个地方有变化
if (light != null)
{
light.color = color;
light.intensity = intensity;
}
}
}
PlayableBehaviour中就不再需要Light成员变量了,因为可以从方法的playerData中获取到,转换成对应的类型即可。
using UnityEngine;
using UnityEngine.Playables;
public class LightControlAsset : PlayableAsset
{
//public ExposedReference<Light> light; 不需要它了
public Color color = Color.white;
public float intensity = 1f;
public override Playable CreatePlayable (PlayableGraph graph, GameObject owner)
{
var playable = ScriptPlayable<LightControlBehaviour>.Create(graph);
var lightControlBehaviour = playable.GetBehaviour();
//lightControlBehaviour.light = light.Resolve(graph.GetResolver());
lightControlBehaviour.color = color;
lightControlBehaviour.intensity = intensity;
return playable;
}
}
PlayableAsset中也不需要再保留ExposedReference<Light>了,轨道会直接提供这个Light对象。
在Timeline中添加
现在就可以在Timeline中直接添加Light Control Track了。
添加Track后,需要设置绑定的对象。这样每个Clip都可以获取到这个绑定的对象。
就可以像内置的Track一样使用啦!
动态绑定
1.动态设置轨道的绑定,就是给上图中Bindings赋值
foreach (PlayableBinding bindingInfo in director.playableAsset.outputs)
bindingInfo.streamName:轨道的名字
bindingInfo.sourceObject:轨道绑定源obj
下面这一行代码就设置好了轨道的绑定
director.SetGenericBinding(bindingInfo.sourceObject, new GameObject(“bindObjName”));
2.获取轨道上的所有clips的信息
TrackAsset trackOne = bindingInfo.sourceObject as TrackAsset
var clips = trackAsset.GetClips().GetEnumerator();
每个clip 有两个属性
clip.displayName: clip的名字
clip. 此clip可查看到它自己inspector面板中的所有信息
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Timeline;
using UnityEngine.Playables;
public class SetTimelineBinding : MonoBehaviour
{
PlayableDirector director;
void Start()
{
director = GameObject.FindGameObjectWithTag("direct").GetComponent<PlayableDirector>();
GetAllOuts();
}
// key:轨道名字 value:轨道对应的绑定源类型
Dictionary<string, Object> Name_BindObj = new Dictionary<string, Object>();
// key:轨道名子 value:{key:clip名字;value:clip信息}
Dictionary<string, Dictionary<string, PlayableAsset>> Track_Clips = new Dictionary<string, Dictionary<string, PlayableAsset>>();
public void GetAllOuts()
{
foreach (PlayableBinding item in director.playableAsset.outputs)
{
Debug.LogError("item.streamName=" + item.streamName);
if (!Name_BindObj.TryGetValue(item.streamName, out var obj))
{
var gameObj = GameObject.Find(item.streamName);
Name_BindObj.Add(item.streamName, item.sourceObject);
}
if (director.GetGenericBinding(item.sourceObject) == null)
{
Debug.LogError("already have binding, name="+ item.streamName);
}
else
{
Debug.LogError("轨道中绑定丢失,轨道名字是Error null binding name=" + item.streamName);
}
if (item.streamName.Equals("Markers"))
{
continue;
}
// 下面是获取每个 Track轨道中所有的clip信息
if (!Track_Clips.ContainsKey(item.streamName))
{
Track_Clips[item.streamName] = new Dictionary<string, PlayableAsset>();
}
TrackAsset trackAsset = item.sourceObject as TrackAsset;
var clips = trackAsset.GetClips().GetEnumerator();
for (; clips.MoveNext();)
{
var cur = clips.Current;
Debug.LogError("Name =" + cur.displayName);
Track_Clips[item.streamName][cur.displayName] = cur.asset as PlayableAsset;
var pa = cur.asset as PlayableAsset;
}
}
}
void SetBindings()
{
var iEnumtor = Name_BindObj.GetEnumerator();
for (; iEnumtor.MoveNext();)
{
var cur = iEnumtor.Current;
var obj = GameObject.Find("example");
SetGenericBindOne(cur.Key, obj);
}
}
void SetGenericBindOne(string trackName,Object obj)
{
director.SetGenericBinding(Name_BindObj[trackName], obj);
}
}