Playable API周りについての概要がなんとなくわかってきたので、次にScriptablePlayableを自作してみたいと思い調査をしてみました。 最終目標は独自のTrackをTimelineで再生をすることです。
ScriptPlayable を自作する
ScriptPlayableを作るにはPlayableBehaviourを継承してクラスを作成します。 では適当にPlayableを作ってみます。
public class CustomPlayable : PlayableBehaviour { // PlayableGraph再生時 public override void OnGraphStart(Playable playable) { Debug.Log("Graph Start"); } // PlayableGraphストップ時 public override void OnGraphStop(Playable playable) { Debug.Log("Graph Stop"); } }
これはPlayableGraphで使って見ます。
_playableGraph = PlayableGraph.Create(); var customPlayable = ScriptPlayable<CustomPlayable>.Create(_playableGraph, 0); animationPlayableOutput.SetSourcePlayable(customPlayable); var scriptOutput = ScriptPlayableOutput.Create(_playableGraph, "custom"); scriptOutput.SetSourcePlayable(customPlayable); _playableGraph.Play();
Unityで再生するとPlayableGraph Visualizerではこのように表示されています。 (デバックログも吐き出されています)
ProcessFrame
PlayableBehaviourにProcessFrameというメソッドが定義されています。 PlayableGraph再生時の経過情報を受け取ることができます。
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
}
FrameDataにはdeltaTimeなどの情報がありますのでこれを使うことで、何かしらのアニメーションを設定できたりできそうです。
Playableの時間を設定する
現状、Unity再生中にこのPlayableはずっと再生されています。 次に、Playableの再生時間を設定する方法を調べます。
public override void ProcessFrame(Playable playable, FrameData info, object playerData) { var time = playable.GetTime(); var duration = playable.GetDuration(); }
現在の経過時間はPlayableのGetTimeで取得でき、Playableの再生時間はGetDurationで取得ができます。 これを使い、必要な処理を行うことができます。
再生時間はPlayableのSetDurationで指定できます。
playable.SetDuration(1.0f);
ProcessPrameは経過時間を過ぎても呼び出し続けますので、もし止めたい場合には playable.Pause()を呼び出します。
playable.Pause();
Timelineで使いたい
Playableについて少しわかってきたので、当初の目的であるTimelineで使えるようする方法が調べました。
必要なクラス
TImelineで用意するためには次の3つを表示できるクラスです。
- Track
- Playable
- PlayableAsset (Clip)
Playableを定義する
TImelineが再生されたときのClipの挙動をPlayableで作成されています。 今回はUGUIのImageの色を変更するできるように実装をしました。
public class CustomTimelineClipPlayable : PlayableBehaviour { public Color StartColor = Color.white; public Color EndColor = Color.white; public override void ProcessFrame(Playable playable, FrameData info, object playerData) { var image = playerData as Image; if (image != null) { var duration = playable.GetDuration(); var time = playable.GetTime(); image.color = Color.Lerp(StartColor, EndColor, (float) (time / duration)); } } }
Color.Lerpを使って色変化を実装しているのですが、もしかしたらもっと良い方法あるかもしれません。
PlayableAsset
次にTimeline上にClip表示と編集ができるようにPlayableAssetを作成します。 今回はImageの始値と終値を設定できるようにしました。
[System.Serializable] public class CustomTimeLinePlayableAsset : PlayableAsset { public Color startColor = Color.white; public Color endColor = Color.white; // Factory method that generates a playable based on this asset public override Playable CreatePlayable(PlayableGraph graph, GameObject go) { var playable = ScriptPlayable<CustomTimelineClipPlayable>.Create(graph); var behaviour = playable.GetBehaviour(); // PlayableへInspectorでの設定値を渡しています。 behaviour.StartColor = startColor; behaviour.EndColor = endColor; return playable; } }
Trackを自作する
Timelineで使うTrackを作成します。
[TrackClipType(typeof(CustomTimeLinePlayableAsset))] [TrackBindingType(typeof(Image))] public class CustomTimelineTrack : TrackAsset { }
TrackBindingTypeで対象のImageを設定できるようにしています。
確認
これで準備完了です。 TimelineでTrackを作成するときに、新しく「CustomTimelineTrack」が選択できるようになっているはずです。
最後に
とりあえず、自作のPlayableをTimeline上で動かせるようになりました。 ただ、簡単なPlayableでしたので、今後はもう少し複雑なPlayableが作れるようにしたいないと思いました。