TimeLine其强大的地方就在于其扩展性,其中ChineCamera就是支持其扩展。默认只支持以下几个有限的功能。大部分还是需要我们自己进行扩展,才能发挥出TimeLine的潜力。
本文以一个简单的Rotate 的Playalbe 为例:
PlayableAsset代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
//version 0.5
[System.Serializable]
public class RotatePlayable : PlayableAsset
{
public ExposedReference<GameObject> Target;
public float Speed = 1;
public Vector3 Axis = Vector3.up;
// Factory method that generates a playable based on this asset
public override Playable CreatePlayable(PlayableGraph graph, GameObject go) {
var scriptPlayable = ScriptPlayable<RotatePlayableBehaviour>.Create(graph);
//从ExposedReference中获取我们需要的控件
scriptPlayable.GetBehaviour().Target = Target.Resolve(graph.GetResolver());
//对指定的PlayableBehaviour中的属性进行赋值
scriptPlayable.GetBehaviour().Axis = Axis;
scriptPlayable.GetBehaviour().Speed = Speed;
return scriptPlayable;
}
}
大概过程:
1. 先建立一个PlayableTrack,它是自定义扩展的载体
2. 右键就会显示我们扩展的组件。
3. 选择后可以在右侧inspector里进行配置。(本例Speed就是Rotate一圈需要的时间)
4. 在CreatePlayable中把面板中的配置项传入到PlayableBehaviour中。
5. PrepareFrame中(类似Update)中进行对应的动作,本例就是Rotate。
PlayableBehaviour代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
//version 0.5
// A behaviour that is attached to a playable
public class RotatePlayableBehaviour : PlayableBehaviour
{
public GameObject Target;
public float Speed;
public Vector3 Axis;
private float offsetPS;
// Called when the owning graph starts playing
public override void OnGraphStart(Playable playable) {
base.OnGraphStart(playable);
}
// Called when the owning graph stops playing
public override void OnGraphStop(Playable playable) {
base.OnGraphStop(playable);
}
// Called when the state of the playable is set to Play
public override void OnBehaviourPlay(Playable playable, FrameData info) {
base.OnBehaviourPlay(playable, info);
offsetPS = 360.0f / Speed;
}
// Called when the state of the playable is set to Paused
public override void OnBehaviourPause(Playable playable, FrameData info) {
base.OnBehaviourPause(playable, info);
}
// Called each frame while the state is set to Play
public override void PrepareFrame(Playable playable, FrameData info) {
base.PrepareFrame(playable, info);
Target.transform.Rotate(Axis, offsetPS * info.deltaTime);
}
}
注意TimeLine的特性:
1. Time.TimeScale会影响Timeline的运行。可以根据其来实现一些暂停的功能。
https://docs.unity3d.com/ScriptReference/Playables.DirectorUpdateMode.html
可以根据以上进行修改,不受Scale的影响。
2.没有OnBehaviourStop方法,可以通过Asset获取到对应的duration,做个Timer进行相关的Stop操作
3.就像其名字一样,只支持串行时间管理,如果要循环比如本例的一些Rotate的过程,需要自己实现。
4.由于Timeline是种静态的资源,普通的Public定义不能绑定到Runtime即Hierarchy窗口中的对象。如果在支持绑定需要使用ExposedReference模板进行定义。
5. Stop再进行Play会重新开始播放
6. 在调节动画时,如果Scale变化了,再通过修改Position和Rotate会出问题,修改后,下一帧自动变为Scale后的变化,应该是BUG。