[Unity][Timeline] ControlTrackを扱う上で注意すること

## 初めに
`ControlTrack`はシーン上のObjectを操作したり、Prefabの生成を制御したりすることができる標準のトラックです
今回はこの`ControlTrack`にはどのような機能があるのか、そしてそれらの機能はどのように動いているのかを軽く説明しつつ、それに合わせた注意点を私なりにまとめてみました

簡単に言うと**あまり考えずに沢山使うとパフォーマンスに影響出るかもよ？**というのを長々と書き連ねています

## `ControlTrack`の機能
`ControlTrack`にクリップを生成したときにInspectorから編集することができる`ControlPlayableAsset`にあるパラメータに`ControlTrack`でできることがまとまっています

### Control Activation
`Source Game Object`に設定したシーン上のオブジェクト または `Prefab`に設定したプロジェクト内のPrefabオブジェクトのActive状態を操作します

`Prefab`を設定した場合は`Source Game Object`の項目が`Parent Object`に変わり、そこに設定したシーン上のオブジェクトを親オブジェクトとして`Prefab`を`Instantiate`します

クリップの設定されている時間の間に指定した`GameObject`または`Prefab`のアクティブ状態を`true`にします

`Post Playback`オプションでクリップの再生終了時にアクティブ状態をどのようにするかを設定できます

|PostPlaybackState|説明|
|:--|:--|
|Active|アクティブ状態にする|
|Inactive|非アクティブ状態にする|
|Revert|再生開始時の状態に戻す|

### Control PlayableDirector
Inspectorから`ControlPlayableAsset`を操作する際に`Advanced`のFoldoutを開くと出てくるオプション

`Source Game Object`に設定したシーン上のオブジェクト または `Prefab`に設定したプロジェクト内のPrefabオブジェクトから`PlayableDirector`のコンポーネントを取得してクリップの再生時間や状態を伝えてくれるようになります

### Control ParticleSystem
Inspectorから`ControlPlayableAsset`を操作する際に`Advanced`のFoldoutを開くと出てくるオプション

`Source Game Object`に設定したシーン上のオブジェクト または `Prefab`に設定したプロジェクト内のPrefabオブジェクトから`ParticleSystem`のコンポーネントを取得してクリップの再生時間や状態を伝えてくれるようになります

`Random Seed`には`ParticleSystem`の`Random Seed`値に対して任意のシード値を設定できるようになっています
※勝手にランダムな値に初期化されるのでただ使うだけであれば意識する必要はない

### Control ITimelineControl
Inspectorから`ControlPlayableAsset`を操作する際に`Advanced`のFoldoutを開くと出てくるオプション

`Source Game Object`に設定したシーン上のオブジェクト または `Prefab`に設定したプロジェクト内のPrefabオブジェクトから`ITimelineControl`を継承したコンポーネントを取得してクリップの再生時間や状態を伝えてくれるようになります

### Control Children
Inspectorから`ControlPlayableAsset`を操作する際に`Advanced`のFoldoutを開くと出てくるオプション

`Source Game Object`に設定したシーン上のオブジェクト または `Prefab`に設定したプロジェクト内のPrefabオブジェクトの子オブジェクトに対しても上記の制御機能を伝播させるかどうかを設定します

## 注意点

### Control Activation
このフラグが立ったときに内部で使われるようになる`ActivationControlPlayable`が`OnProcessFrame`内で問答無用に`gameObject.SetActive(true)`を呼び続けます

これが何を意味するかというと**このフラグが立っているクリップの数だけ`gameObject.SetActive(true)`が毎フレーム呼ばれ続けることを意味しています**

単体で見るとそこまで処理コストがかかる処理でもないのですが、`ControlPlayableAsset`を持ったクリップが沢山同時間に並んでいればいるほどその処理コストが重なっていくことを考えるとあまりこのオプションを使いたくありません

なのでこの機能はどうしても必要なとき以外は切っておくのが良いと思います
※`ControlTrack`以外からもそのオブジェクトが操作される可能性があり、状況によっては再生中に外側から非アクティブ状態にされてしまうなどと言った場合は使用したほうが良いでしょう

### Control PlayableDirector / ParticleSystem / ITimelineControl
前述の機能の項目の通り、このフラグが立つと各種コンポーネントに対してクリップの再生時間と状態を操作してくれるようになりますが、**シーン上のオブジェクトを`SourceGameObjectに設定した場合、内部的に使用してくれるコードの中ではオブジェクトのアクティブ状態を切り替えてくれません**

もし制御する想定のオブジェクトのアクティブ状態がオフになるような状況が発生してもクリップからの制御は正しく動作してほしいといった場合は`Control Activation`のフラグを立てておく必要があります
そうしないとオブジェクトが非アクティブ状態のままクリップから操作されようとして動かないといったことが起きる可能性があります

※`Prefab`を設定したときには、`Prefab`を`Instantiate`する用の`PrefabControlPlayable`が合わせて`PlayableGraph`に登録されるのですが、そこでは`OnBehaviourPlay`(再生開始)と`OnBehaviourPause`(再生停止)のタイミングでアクティブの切り替え処理を明示的に呼んでいるため、上記のような考慮は必要ありません
 
### Control Children
このフラグが立つと、制御対象の`GameObject`からオプションに合わせたコンポーネントの参照を取得する際に`GetComponentsInChildren`メソッドを使うようになります

`PlayableGraph`がビルドされるタイミングに一度だけしか呼ばれないのでそこまで気にする必要はないかもしれませんが、階層が深い`GameObject`の場合はそれだけ下の階層まで走査していくことになるはずなので処理コストが増える可能性があります

小要素までクリップの再生時間や状態を伝播させる必要がないのであればこのオプションは切っておくほうが無難でしょう

## 最後に
設定できる項目はシンプルですが、状況によっては使い方に気を配らなければならないケースが出てくるというお話でした
Timline機能をガッツリ使ってカットシーンを作るというような場合などは気をつけておきたいです