自定义TimeLine

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。

发布了51 篇原创文章 · 获赞 10 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/FeiBin2013/article/details/85615783