CreatePlayable周りの調査。AssetからBehaviourを、BehaviourからBindingを参照したい
CreatePlayable周りがちょっとややこしかったので調査
まず初めに断っておくが、本来はMixerを作るのがベストだが、今回はあえてMixerを作らずに頑張ってみる
ScriptPlayable
var playable = ScriptPlayable<NewPlayableBehaviour>.Create(graph); var trackBinding = go.GetComponent<PlayableDirector>().GetGenericBinding(this) as GameObject; playable.GetBehaviour().target_ = trackBinding; return playable;
前回はこのようにしてBehaviourにバインディングを渡した
もちろん、単なるプロパティ経由なのでどんなものでも渡せる
ただし、この場合 PlayableAsset::CreatePlayableが呼ばれない
そのため、PlayableAssetがBehaviourを知る方法がメンドクサイなど問題が生じる
なので、この方式を変更しようと思う
TrackAsset::CreatePlayable
BaseClassのCreatePlayableを呼ぶと、その中からPlayableAsset::CreatePlayableが呼ばれるようになる
具体的には
NewPlayableTrack
return base.CreatePlayable(graph, go, clip);
Assetの方は下記コードで、Behaviourの参照を手に出来る
templateという変数名にするのが通例のようだ
今回は template_というプロパティーを持たせる
public NewPlayableBehaviour template_; public override Playable CreatePlayable(PlayableGraph graph, GameObject go) { return ScriptPlayable<NewPlayableBehaviour>.Create(graph, template_); }
前にコード書いたときは上記で、template_にBehaviourの参照が渡ってきた覚えがあるが
コード間違えたかUNITYのバージョンか覚え違いか、Nullだったので変更した
public NewPlayableBehaviour template_; public override Playable CreatePlayable(PlayableGraph graph, GameObject go) { var playable = ScriptPlayable<NewPlayableBehaviour>.Create(graph); template_ = playable.GetBehaviour(); return playable; }
これで確実にtemplate_にbehaviourが設定される
上記で対応できると思ったが、Inspectorを作る時に不具合が生じる。今のところUNITY2020で問題が起こっている・・
UNITY2020では異なる方法で行う必要があるかもしれないので
今後は少し古いが UNITY2019.4での作業に変更
Bindingを渡したい
BehaviourにてトラックにBindingされたオブジェクトの操作をしたい事は多々ある
が、UNITYのTimelineはBehaviourから簡単にBindingが参照できない(ほんとこれは不便)
なので、どこかでBindingを渡す必要がある
まずBindingの取得方法だが、TrackAsset::CreatePlayable あるいは、PlayableAsset::CreatePlayableの引数の
GameObjectが、タイムラインのGameObjectになっていて
そこからPlayableDirectorコンポーネントを取得し、その中のBindingsから該当するトラックのBindingを検索する
具体的なコードは
var trackBinding = go.GetComponent<PlayableDirector>().GetGenericBinding(key) as GameObject;
もちろんこのgoがGameObjectだが、問題はこのKeyである
Directorから何らかの方法でKeyを取得できるかもしれないが
ここはTrackAssetのthisを渡すのが簡単なので、TrackAssetから渡したい
結果
NewPlayableTrack
[TrackBindingType(typeof(GameObject))] [TrackClipType(typeof(NewPlayableAsset))] public class NewPlayableTrack : TrackAsset { protected override Playable CreatePlayable(PlayableGraph graph, GameObject go, TimelineClip clip) { Playable playable = base.CreatePlayable(graph, go, clip); var trackBinding = go.GetComponent<PlayableDirector>().GetGenericBinding(this) as GameObject; Debug.Log("Track::" + trackBinding); var p = (ScriptPlayable<NewPlayableBehaviour>)playable; p.GetBehaviour().binding_ = trackBinding; return playable; } }
NewPlayableAsset
public class NewPlayableAsset : PlayableAsset { public NewPlayableBehaviour template_; public override Playable CreatePlayable(PlayableGraph graph, GameObject go) { var playable = ScriptPlayable<NewPlayableBehaviour>.Create(graph, template_); return playable; } }
以上で
PlayableAssetからは templateという名前でBehaviourが扱え
PlayableBehaviourからは bindingという名前でトラックにバインドされたオブジェクトが扱える