テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】Timelineのクリップが動かすオブジェクトを動的に更新する方法

f:id:tsubaki_t1:20170922224305g:plain

今回は、昨日紹介したControlTrackのControl Playable Asset Clipに、任意のオブジェクトを動的にバインドする方法についてです。

Timelineの中身を動的に更新したい

Timelineを映像系ではなくゲームで使用する場合、実行時に動的に操作する対象を差し替えたくなるといったケースがあるかもしれません。

 

例えばITimeControlで操作するGameObjectを差し替えたり、Cinemachineで参照するVirtual Cameraを切り替えたり、動かすキャラクターを差し替えたり。

 

動かすキャラクターといったTrackで制御する物に関しては、下の記事の方法で解決出来ますが、クリップに関しては少し面倒です。

tsubakit1.hateblo.jp

クリップの値は参照する物と実体を持つものがある

f:id:tsubaki_t1:20170922214702j:plain

クリップの値ですが、少し複雑です。

 

通常、クリップの値は、Timelineのアセット(PlayableAsset)が保持しています。この値はアセットとして保持されていて、基本的に固定値のような扱いです。

ただし、シーン内のオブジェクトを参照するような内容…例えばGameObjectやAnimatorへの参照等は、PlayableDIrectorからPlayableAssetが吸い出して解決するような方法で解決しています。

 

この意味は、値を保持するタイプの物は動的に書き換えると他のすべてのTimelineが影響してしまいますが、参照のみの場合はPlayableDirectorの値をチョチョっと書き換えてやれば、捜査対象をハック出来るという意味です。

Control Playable Asset Clipの参照先を書き換える

せっかくなので、昨日紹介したControl Playable Asset Clipの参照先を切り替えてみます。

サンプルコードはこちら。

gist.github.com

解説

まず15行目、名前からトラックを取得します。
トラック名は、Inspectorで書き換えられます。

f:id:tsubaki_t1:20170922220008j:plain

 

次に16行目、トラック一覧から上書きしたいクリップを取得します。
こちらも同様にInspectorから書き換え可能です。

f:id:tsubaki_t1:20170922220019j:plain

 

そして18行目で、オブジェクトが参照を解決するためのキーを取得し、19行目で値を登録します。

ここで注意すべきは、Control Playable Asset ClipはITimeControlではなくGameObjectを受け付けるという点です。なので、コンポーネントからGameObjectを取得して渡します。

実際に動かす例

コードを用意したら、PlayableDirectorのあるオブジェクトにRebindコンポーネントを追加します。

その後、ボタン等でRebindのPlayメソッドをITimeControlを持ったオブジェクトを引数にして呼び出してやれば、回転します。

f:id:tsubaki_t1:20170922220733j:plain

f:id:tsubaki_t1:20170922222141g:plain

もっと手っ取り早い方法

ちなみに、対象がControl Playable Asset Clipの場合はもっと手っ取り早い解決方法があります。

実はControl Playable Asset Clipは子オブジェクトも動かすオプションがあります。このオプションがonの場合、SourceGameObjectの子のITimeControlも一緒に操作してくれます。

f:id:tsubaki_t1:20170922222939j:plain

要するに、事前に用意したオブジェクトの子として、指定のオブジェクトを動かしてやるというアプローチです。
下のような動作をソースコード側でやります。

f:id:tsubaki_t1:20170922223624g:plain

手順

まず、適当な親オブジェクトを用意します。名前はBindedObjectとか適当にそんな感じで。

次に、ControlPlayableAssetにBindedObjectを登録します。

f:id:tsubaki_t1:20170922223201j:plain

後は、動的にオブジェクトの子として動かしたいオブジェクトを登録します。先程のコードを少し改造したものです。

gist.github.com

これでも、動的にオブジェクトが更新されます。

既に動作してるTimelineは更新出来ない点に注意

一点だけ注意があります。

それはこの方法では既に動作しているTimelineの参照を上書きできないという点です。

 

Timelineの参照解決はTimeline再生開始時に行われるのが通例らしく、参照関係を解決した後に流し込む内容を更新しても意味がないという事みたいです。

ちなみにPreviewのON/OFFでも参照関係の構築が走るみたいなので、上手く動かないときはPreviewをON/OFFすると解決するかもしれません。わんぽいんと

 

次はTImelineの階層化とかパーティクルとか

関連

tsubakit1.hateblo.jp

https://forum.unity.com/threads/timeline-available-in-unity-2017-1.455265/page-6#post-3217752

tsubakit1.hateblo.jp