[Unity] [Timeline拡張]  ○○BehaviourでTrackにセットしたオブジェクトを取得する

テラシュールさんで追記予定と書かれて放置されている○○BehaviourでTrackのオブジェクトを取得する方法を見つけたので、知見を共有します。

お世話になったサイト
[テラシュールブログ: 【Unity】TimelineでOnBehaviourPlayのタイミングでTrackの情報を使って初期化したい](http://tsubakit1.hateblo.jp/entry/2018/08/27/233000)
[LIGHT11: 【Unity】【Timeline】ブレンドも可能なカスタムクリップを持つカスタムトラックの作り方](http://light11.hatenadiary.com/entry/2019/05/16/214328)

環境 
`unity2018.3.6`


## 方法
やり方としては、○○MixerBehaviourのOnGraphStartで、Trackにバインドしたオブジェクトを取得と同時にfor文で全clipに取得したオブジェクトを渡します。あとは○○BehaviourのOnBehaviourPlayで初期化なり、値を取得するなりできるという算段です。

## ソースコード
ここではTrackにバインドしたGameObjectを取得する例をあげます。

```c#:TestBehaviour.cs
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

[Serializable]
public class TestBehaviour : PlayableBehaviour {

    public GameObject trackObj;

    // 各clip開始時に呼び出される
    public override void OnBehaviourPlay (Playable playable, FrameData info) {
        if (!trackObj)
            return;
        

        // なんらかの処理


    }
}
```

```c#:TestClip.cs
using System;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

[Serializable]
public class TestClip : PlayableAsset, ITimelineClipAsset {
    
    public TestBehaviour template = new TestBehaviour ();

    public override Playable CreatePlayable (PlayableGraph graph, GameObject owner) {
        // TestBehaviourを作成
        var playable = ScriptPlayable<TestBehaviour>.Create (graph, template);
        return playable;
    }
}
```




```c#:TestMixerBehaviour.cs
using System;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

public class TestMixerBehaviour : PlayableBehaviour {
    // トラックに入っているGameObject
    public GameObject m_TrackBinding;

    // timelineの開始時 初期化
    public override void OnGraphStart (Playable playable) {
        if (!m_TrackBinding)
            return;

        // Trackの全clipの数を取得  
        int inputCount = playable.GetInputCount ();

        for (int i = 0; i < inputCount; i++) {
            // 各clipのbehaviour取得
            ScriptPlayable<TestBehaviour> inputPlayable = 
                (ScriptPlayable<TestBehaviour>) playable.GetInput (i);
            TestBehaviour input = inputPlayable.GetBehaviour ();
            // trackのGameObjectを渡す
            input.trackObj = m_TrackBinding;
        }
    }
}
```

```c#:TestTrack.cs
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

[TrackClipType (typeof (TestClip))]
[TrackBindingType (typeof (GameObject))]
public class TestTrack : TrackAsset {

    public override Playable CreateTrackMixer (PlayableGraph graph, GameObject go, int inputCount) {
        // TestMixerBehaviourを作成
        var playable = ScriptPlayable<TestMixerBehaviour>.Create (graph, inputCount);
        var trackBinding = go.GetComponent<PlayableDirector> ().GetGenericBinding (this) as GameObject;
        // TrackにバインドされたGameObjectをTestMixerBehaviourに渡す
        playable.GetBehaviour ().m_TrackBinding = trackBinding;
        return playable;
    }
}
```

以上のようなコードで、Timelineの再生ボタンを押した時にTestMixerBehaviour.csのfor文が走り、全部のclipにバインドされたGameObjectが参照され、各clipの開始時にいろいろ処理ができるというコードができました。

---
ほかにもっとスマートな方法がありましたら、教えていただけると助かります。