Timelineについての覚書です。
TL;DR
- 図を使い全体像を俯瞰的に把握することでTimelineのシルエットを掴む。
- 具体的な使い方とか実装方法は含まない。
- カスタムトラックは関連性を図示し、Default Playables のWizardで生成されるコードとサンプルプロジェクトで使用していたTipsを埋め込んだサンプルコードを記載。
- Webから入手可能なTimelineの機能拡張を含むサンプルプロジェクトや情報の紹介。
- 付録にオブジェクトの情報をダンプしたログを記載。
目次
- TL;DR
- 目次
- 環境
- Timeline の概要
- 機能拡張
- 参考
- Webのサンプル
- Shallow Dive Timeline
- 付録1
- 付録2
- PlayableDirector
- playableGraph
- PlayableDirector.playableGraph
- PlayableDirector.playableGraph.GetRootPlayable(0)
- PlayableDirector.playableGraph.GetOutput(i)
- PlayableDirector.playableGraph.GetOutput(i).GetSourcePlayable()
- PlayableDirector.playableGraph.GetOutput(i).GetSourcePlayable().GetInput(i)
- PlayableDirector.playableGraph.GetOutput(i).GetReferenceObject()
- playableAsset
- Clipの動き
環境
- Unity 2019.4.25f1
- Timeline 1.6.3
- Default Playables 1.8.0
※公式ドキュメントへのリンクは、バージョンによってページがあったりなかったりするので、飛び先のバージョンがバラバラなのは注意してほしい。
Timeline の概要
Playables API
そもそもは Playables API が存在する。 Playables API は PlayableGraph というツリー構造のデータソースを構築し再生することができる。 アニメーションやオーディオ、スクリプトをサポートしており、AnimationControllerの内部でも利用されているLowLevelなAPI群。 複数のデータソースをミックスしたりブレンドしたりもできる。 構築した内容は時系列で(フレーム毎に)出力される状態が評価され、再生することで連続的に状態が変化して動きを生む。
PlayableGraph Visualizer
PlayabGraph はグラフを可視化する PlayableGraph Visualizer というパッケージが提供されている。 導入するとWindowはAnalysisから開けるようになる。
About PlayableGraph Visualizer | Package Manager UI website
PlayableGraph Visualizerでは、IPlayable、IPlayableOutput、IPlayableBehaviourなオブジェクトがノードとして表示される。 上の図では、ScriptOutputがIPlayableOutput、TimelineとActivationMixerがIPlayableBehaviour、PlayableがIPlayableなオブジェクトである。
PlayableGraph Visualizerは、Timelineから複数のPlayableOutputを出力するように描画できないため、TimelineのTrackが増えるとTrackの数だけ複製して描画されるようになる。 Timelineから右は再生中の動きも含め全部同じであり、左端のPlayableOutputだけがTrack毎に定義される。 このグラフ自体はスクロールや拡大縮小などできないため、複数描画されてツリーが小さく表示されるとノードが見えなくなるし、ノードをクリックするのも困難になるので参考程度にしか使えない。
Timeline
Timeline は PlayableGraph をエディタで視覚的に作成、編集できるようにした仕組み。 Timeline エディタで時系列に状態を定義することができ、定義した内容を永続化してくれる。 Timeline 自体は ScriptableObject でアセットとして保存されるので、Sceneで利用する時はバインディングを使ってGameObjectと関連付けられる。そのため、バインディング内容を変更するなど再利用が可能である。 また、機能を拡張するための機構も用意されている。
標準機能
Timeline では以下の機能が用意されている。
Track
- ActivationTrack
- BindingType:GameObject
- Clip:ActivationClip
- GameObject のアクティブ状態を制御する
- AnimationTrack
- BindingType:Animator
- Clip:AnimationClip
- Animator のアニメーションを再生する
- AudioTrack
- BindingType:AudioSource
- Clip:AudioCilp
- AudioClip を再生する
- ControlTrack
- BindingType:-
- Clip:(ControlPlayableAsset)
- Activation
- Prefabのインスタンス化
- PlayableDirector
- ParticleSystem
- ITimeControl
- 最も単純な拡張機構
- ClipのPlay中に毎フレーム呼ばれる
- Clipの開始時間やDurationなどの情報が取れないのでただ毎フレーム処理するだけ
- GameObjectの時間に関連する要素を制御する
- PlayableTrack
- BindingType:-
- Clip:カスタムクリップ
- カスタムクリップを再生する
- カスタムクリップを作成し再生することができる拡張機構
- カスタムトラックでTrackClipTypeを指定されているカスタムクリップは除外される
- SignalTrack
- BindingType:SignalReceiver
- Clip : Signal / Marker
- バインディングされたレシーバーに信号を送信する
- GroupTrack
- BindingType:-
- Clip : Track
- Trackを階層的に並べられるコンテナ
Marker
- Signal
- SignalをSignalReceiverに紐付けて処理を呼び出せる
- 1つのReceiverは、1つのSignalに1つの処理を紐付けられる
- 呼び出す処理が違う場合はSignalの定義を増やす必要がある
- Signalはアセット
- Marker
- 1つのMarkerの定義で、配置毎にパラメータを設定することができる
- 拡張機構
- 作成するには以下の実装が必要
- Marker, INotification を実装したMarkerクラス
- INotificationReceiver を実装したReceiverクラス
- 機能を持たないエディタ上でマークするだけのMarkerであれば INotification とReceiverの実装は不要
- Webのサンプルにあった例
- TimeScaleの制御
- 特定フレームへのジャンプ
- Timelineエディタ上での注釈
Default Playables
公式が配布しているパッケージ。 Timelineのカスタムトラック一式を作成するためのテンプレートを生成してくれる「Timeline Playables Wizard」とカスタムトラック一式の例が含まれる。
Default Playables | Essentials | Unity Asset Store
Track
- LightControlTrack
- BindingType:Light
- Clip : LightControlClip
- ライトを制御する
- NavMeshControlTrack
- BindingType:NavMeshAgent
- Clip : NavMeshAgentControlClip
- NavMeshAgentの宛先を制御する
- ScreenFaderTrack
- BindingType:Image
- Clip : ScreenFaderClip
- 画像を使ったフェードを制御する
- TextSwitcherTrack
- BindingType:Text
- Clip : TextSwitcherClip
- テキストを制御する
- TimeDilationTrack
- BindingType:-
- Clip : TimeDilationClip
- TimeScaleを制御する
- TransformTweenTrack
- BindingType:Transform
- Clip : TransformTweenClip
- StartとEndに指定したTransform間を移動する
- VideoScriptPlayableTrack
- BindingType:-
- Clip : VideoScriptPlayableAsset
- VideoPlayer componentを介してビデオを再生する
Cinemachine
Cinemachineのパッケージが入っているとCinemachineの機能が使えるようになる。
Track
- CinemachineTrack
- BindingType:CinemachineBrain
- Clip : CinemachineShot
- Cinemachineのカメラワークを制御する
機能拡張
Timelineで機能拡張する方法は3つ存在する。
ITimeControl
- ControlTrack + ITimeControlを実装したComponent
- 最も単純な拡張機構
- ClipのPlay中に毎フレーム呼ばれる
- Clipの開始時間やDurationなどのClip情報が取れないのでただ毎フレーム処理するだけ
カスタムクリップ
- PlayableTrack + カスタムクリップ
- カスタムクリップを作成すると再生することができる拡張機構
- カスタムトラックでTrackClipTypeに指定されているカスタムクリップは除外される
- 自身のClipの情報を取得できる
- Clip間にまたがる処理はできない(Weightを使ったブレンドなど)
- 作成するには以下の実装が必要
- Clip
- PlayableAsset, ITimelineClipAsset を実装したClip相当の PlayableAsset クラス
- PlayableBehaviour を継承したClipの振る舞い相当の PlayableBehaviour クラス
- Clip
- Webのサンプルにあった例
- 動画の字幕
カスタムトラック
- 独自のTrack、MixerPlayableBehaviour 、Clip、PlayableBehaviourを実装する
- 作成するには以下の実装が必要
- Track
- TrackAsset を継承した Track 相当の TrackAsset クラス
- PlayableBehaviour を継承したClip間のブレンドを担当する MixerPlayableBehaviour クラス
- Clip
- PlayableAsset, ITimelineClipAsset を実装したClip相当の PlayableAsset クラス
- PlayableBehaviour を継承したClipの振る舞い相当の PlayableBehaviour クラス
- Track
- Webのサンプルにあった例
Timeline エディタ周りのカスタマイズ
- [Unity][Timeline] Unity2019.2から使えるようになったTrackEditorでトラックの見た目を拡張する - Qiita
- [Unity][Timeline] Unity2019.2から使えるようになったClipEditorでクリップの見た目を拡張する - Qiita
- DrawBackgroundやOnClipChangedでClipの見た目を更新したりできる
- Property Drawer - Unity マニュアル
- ClipのInspectorで独自の動きをするプロパティを定義したり
- Clipの範囲を超えたルールを適用したり
参考
Timelneを調べるに当たり参考にしたページ集。 使い方や解説なども含まれるので勉強する際には参考になれば。
Webのサンプル
Timelineパッケージのサンプル
- AnnotationMarker
- ブックマークとして使用できるマーカーを提供します。
- TextTrack
- TextMeshProテキストコンポーネントを使用して画面にさまざまなメッセージを表示するために使用できるトラックを提供します。
- TimeDilation
- Time.timeScale を調整するために使用できるトラックを提供します。
- Tween
- 単純な変換動作に使用できるトラックを提供します。
- Video
- ビデオクリップを再生できるトラックを提供します。
ATerribleKingdom
- AICommand
- Dialogue
- Light
- TimeMachine
- TMPTextSwitcher
Danmaku
- Dialogue
- PathWalker
【Unite 2018 Tokyo】Timeline機能拡張:カットシーンにとどまらない新たな使い方
Danmaku Shooter - Timeline Scripting Example.zip - Google ドライブ
Cinemachine-market
- ScrollingText
- TMPTextSwitcher
GitHub - ciro-unity/cinemachine-market: Small demo of some various uses of Cinemachine
TimelineMarkerCustomization
- JumpMarker
- AnnotationMarker
同人誌
使い方やアイデアなどコードのない事例も含む。
Aiming Teck Book 2
- エフェクト再生のCustomTrack
- イベント発生のCutomTrack
- TimelineCombination : 複数のTimelineを指定したFrameで再生していく機能
- Muteを使ってアビリティ効果の適用範囲を制御
UniTips 7
- Clipの文字、警告、Clipのカラー、右クリックメニューなどClipのカスタマイズ
Shallow Dive Timeline
Playables API や Timeline 周りはとにかく混乱しがちで難易度が高い。 いくつか理由を挙げてみる。
- "Playable"という単語がそこかしこに名付けられていて区別がしづらい
- 同じクラスを継承するレベルの違うクラス群が入れ子構造になっている
- 戻り値の型が抽象クラスだったりモノによってはObjectだったりして実体が覚えられない
- internalとかprivateとかNativeとか、アクセスできない情報が多い
Timeline の概要で説明したように、TimelineとPlaybles API(PlayableGraph)の関係性がまず大前提として知っておくべきことである。 Timeline は PlayableGraph をエディタで視覚的に作成、編集できるようにした仕組みであり、永続化と機能拡張できる機構が備わっている。あくまで実体は PlayableGraph の方にある。
クラスの関連図
TimelineとPlaybles APIの主要なクラスの関係性を図示する。
次に各名前空間の参照関係である。主要なクラスは4つに別けられていて、Playablesにコア機能がありそれぞれ参照する形になる。
Playable / PlayableOutput
Playable は PlayableGraph で相互に接続できるノードであり、ノードに接続した子の「重み」または「影響力」などを設定できる。
Playable も PlayableOutput も構造体で、スクリプトでPlayableGraphを辿っても、Graphを構成するための情報くらいしか取れない。取得できる情報の型はPlayable
で統一されている。
ScriptPlayable<T>
は、PlayableBehaviourを使用して独自のカスタムPlayableを作成するための機能である。
PlayableOutput は 接続された Playable の出力先。TimelineだとTrackに相当する。 PlayableOutput からは、Timeline層のTrackを表すTrackAssetと、TrackにバインドしたデータであるUserDataを取得することができる。
PlayableGraphで見ると、左端のAnimationOutputやScriptOutputがPlayableOutput、Animationの方ではTimelineを除く右3つ、Scriptの方では右端の3つがPlayableとなる。
TimelinePlayableとActivationMixerPlaybleはPlayableBehaviourである。(PlayableBehaviourは後述) ちなみにActivationMixerPlayableはinternalなクラスのため、UnityEngine.Timeline外からは参照できない。
PlayableとPlayableOutputでは、各構造体にではなくExtentionsクラスで機能が拡張されている。
- PlayableExtensions
- PlayableOutputExtensions
図に示した名前空間以外に、UnityEngine.Experimental.Playables配下にもPlayableなクラスが用意されている。
- CameraPlayable
- MaterialEffectPlayable
- TextureMixerPlayable
- TexturePlayableOutput
PlayableBehaviour
PlayableBehaviour はユーザー定義の動作をPlayableGraphに追加するためのインターフェスおよび基本クラス。 既定ではControlTrackで使われる機能やPlayableGraphで表示されるTimelineなどが備わっている。 CustomTrackを作成する場合は、ブレンドの仕組みを実装するMixerPlaybleBehaviourとClipの振る舞いを実装するPlaybleBehaviourで利用することになる。
Timeline上では、TrackでClip間を監視するMixerPlayableBehaviourとClipのPlayableBehaviourで入れ子構造のイメージが湧く。実際はPlayableBehaviour以外もGraphに接続されるのでより複雑なツリー構造ができあがる。
PlayableAsset
PlayableAsset はScriptableObjectで、Timelineの設定をアセットに永続化し、実行時にPlayableをインスタンス化するために使用される。
TimelineAssetはTimelineのアセットで1つのTimeline自体を定義し、TrackAssetはTimelineのトラックを定義する。右下のPlayableAssetを継承するクラス群はClipの定義となる。 CustomTrackを作成する場合は、TrackAssetを継承するCustomTrackとPlayableAssetを継承するCustomClipを実装する。 ActivationPlayableAssetはinternalなため、外部からは見えない。
Signal/Marker
MarkerはScriptableObjectで、設定が永続化される。SignalはSignal自体がアセットである。 CustomMarkerを作成する場合は、Markerを継承したCustomMarkerクラスとINotificationReceiverを実装したCustomReceiverクラスを実装する。
PlayableGraph / PlayableDirector / TimelineClip
PlayableGraphは素の構造体である。
PlayableDirectorはIExposedPropertyTableを実装している。 これはTimelineのアセットとScene上のGameObjectやComponentの参照関係を解決するための仕組みを提供している。
TimelineClipは、ClipのPlayableAssetをラップしたクラスでTrackのClipを表す。
オブジェクトブラウザー
オブジェクトブラウザーを使って見れるオブジェクトの一覧。
PlayableDirector
PlayableDirector から取得できる主なデータはPlayableGraphとPlayableAsset(実体はTimelineAsset)の2つである。
PlayableGraphでは、PlayableOutputを出力先としてツリー状にPlayableの数珠つなぎ構造が見て取れる。 GraphおよびPlayableはTimelineAsset(Timelineエディタ上)とは定義の粒度が違うので注意が必要。 PlayableOutputはTrackと対の関係であり、TrackAssetとTrackにバインドされたデータは取得できる。
PlayableAssetは抽象クラスだが実体はTimelineAssetである。 上でも書いた通りGraphとTimelineAssetで定義の粒度は違う。 TimelineAsset以下はTimelineエディターの粒度である。PlayableGraphはもっと細かい粒度となる。
TimelineAssetから実行時の振る舞い(PlayableBehaviour)をたどることはできない。 PlayableBehaviourはGraph上で呼び出されて自分の処理を全うするのみとなる。
PlayableDirectorでTimeline扱う場合は、Directorの再生開始時にGraphが生成され、終了すると破棄される。 Timelineの設定を元に生成されるGraphは、生成された後は動的に関連付けられておらず、生成後にTrackのミュートなどを行っても生成済みのGraphへは反映されない。 Graphへ反映させるにはRebuildGraphする必要がある。 RebuildGraphはPlayableGraphの処理の中からは実行できない。
ControlTrackでPlayableDirectorを入れ子にした場合、子のTimeやSpeedを変更しても効果はない。 SignalやMarkerを使って別のTimelineとして非同期で起動すれば動作する。
Manual再生
timeUpdateModeをManualに設定すると、シーケンスを自分で更新して進めることが出来る。
PlayableDirectorのtimeを更新してEvaluateを呼ぶとシーケンスが進む。PlayableDirector自体のPlayを呼ぶ必要はない。呼んじゃダメ。 timeはdouble型。doubleなのでframeとは誤差が生じる。Timeline上のあるframeを確実に踏めるか怪しい。 増加方向に前回のtimeと値が近ければスムーズな動きができるが、差が大きければコマが飛ぶ。 もちろん前回のtimeより小さければ巻き戻る。
AudioTrackの音はManualだと鳴らないので自分で仕掛ける必要がある。 あるタイミング(厳密じゃなくある程度のタイミング)で再生はできるが、Frame単位で細かく合わせるのは厳しそう。 この他にSignalやMarkerも発火しないので自分で呼ぶように実装が必要。
これら発火しないものに関しては自分で発火させてるだけなので、Manualから途中でGameTimeに切り替えてPlay続行するようなイレギュラーなことをした場合、発火したことにはなっておらず再度実行される。
ヘッダー領域のMarkerに手動で通知する場合のサンプル。
for (int i = 0; i < director.playableGraph.GetOutputCount(); i++) { var output = director.playableGraph.GetOutput(i); var playable = output.GetSourcePlayable().GetInput(i); var track = director.playableAsset as TimelineAsset; // Timelineのヘッダー領域のMarkerにはTrackが存在しない if(output.GetPlayableOutputType() != typeof(ScriptPlayableOutput) || output.GetReferenceObject() != null) continue; foreach (var m in track.markerTrack.GetMarkers().OfType<Marker>()) { if (!(m is INotification)) continue; bool fire = (m.time >= oldTime && m.time < time) || (m.time > time && m.time <= oldTime); if (fire) output.PushNotification(playable, m as INotification); } }
Signal / Marker
Timeline のヘッダー領域とSingalTrackに配置できる。
ONでもOFFでも再生ヘッドが通過した範囲内で過去のSignalで通知が発動していないものがあればPlayのタイミングで発動する。 ONにした場合、再生ヘッドが通過していない範囲の呼ばれていない過去のSginalも発動する。 Manualで自分で通知していた場合はカウントされないので、Modeを切り替えてPlayableDirectorをPlayした場合はPlayのタイミングでも発動するので2度発動することになる。
EmitOnce
OFFの場合通過するたびに発動する。 ONの場合1度発動した後は何度通過しても発動しない。
Group
var timeline = director.playableAsset as TimelineAsset; foreach (var track in timeline.GetRootTracks().OfType<GroupTrack>()) { foreach (var child in track.GetChildTracks()) { this.Log(child.GetGroup().name + "\\" + child.name); } }
キャストが必要な場面
以下は擬似コード。
PlayableDirector.playableAsset as TimelineAsset PlayableDirector.GetGenericBinding() as TrackのBindingType PlayableDirector.GetReferenceValue() as ExposedReferenceのBIndingType TrackAsset.parent as TimelineAsset, GroupTrack, ... TimelineClip.asset as ControlPlayableAsset, AnimationPlayableAsset, CustomClip, ... PlayableBinding.sourceObject as ActivationTrack, AnimationTrack, CustomTrack, ... PlayableGraph.GetResolver() as PlayabledDirector PlayableOutput.GetReferenceObject() as ActivationTrack, AnimationTrack, CustomTrack, ... PlayableOutput.GetUserData() as TrackのBindingType
カスタムトラック
Timeline Playables WizardをでGenerateするとカスタムトラックに関連する4つのクラスが生成される。
TrackとClipの設定の永続化と実行時にPlayableをインスタンス化するCustomTrackとCustomClip。
TrackにまたがってClip間のブレンドなどを処理するCustomMixerBehaviour。
Clip自体の振る舞いを実装するCustomBehaviour。
TimelineAssetはアセットファイル(.playable)として保存されている。
TrackAssetを継承するCustomTrackはTimelineClipを保持しており、TimelineClipはCustomClipを内包する。
CustomTrackとCustomClipはそれぞれのBehaviourを生成する役割を持つ。
以降、生成される4つのクラスと事例で見つけたTipsを埋め込んだサンプルを掲載する。
CustomTrack
[TrackColor(0.4856768f, 0f, 1f)] [TrackClipType(typeof(SimpleCustomClip))] [TrackBindingType(typeof(GameObject))] public class SimpleCustomTrack : TrackAsset { public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount) { var playable = ScriptPlayable<SimpleCustomMixerBehaviour>.Create (graph, inputCount); // スクリプトでデータを受け渡しする場合 // Mixerへ var mixerBehaviour = playable.GetBehaviour(); if (mixerBehaviour != null) { mixerBehaviour.Label = "Label1"; } // Clipへ foreach (var clip in GetClips()) { var asset = clip.asset as SimpleCustomClip; if (asset != null) { asset.ClipInTime = clip.clipIn; asset.StartTime = clip.start; } } return playable; } public override void GatherProperties(PlayableDirector director, IPropertyCollector driver) { #if UNITY_EDITOR // TrackにBindingされたオブジェクトを取得 var trackBinding = director.GetGenericBinding(this) as GameObject; if (trackBinding == null) return; // EditorでInspectorなどのプロパティを編集するためのSerializedObjectを利用 var serializedObject = new SerializedObject(trackBinding); var iterator = serializedObject.GetIterator(); while (iterator.NextVisible(true)) { if (iterator.hasVisibleChildren) continue; driver.AddFromName<Transform>(trackBinding.gameObject, iterator.propertyPath); } #endif base.GatherProperties(director, driver); } }
CustomClip
[Serializable] public class SimpleCustomClip : PlayableAsset, ITimelineClipAsset, IPropertyPreview { public SimpleCustomBehaviour template = new SimpleCustomBehaviour(); public ExposedReference<Transform> transform; public float distance; public ClipCaps clipCaps { get { return ClipCaps.All; } } public double ClipInTime { get; set; } public double StartTime { get; set; } public override Playable CreatePlayable(PlayableGraph graph, GameObject owner) { var playable = ScriptPlayable<SimpleCustomBehaviour>.Create(graph, template); // Inspectorで設定した内容をBehaviourに反映する SimpleCustomBehaviour clone = playable.GetBehaviour(); clone.transform = transform.Resolve(graph.GetResolver()); clone.distance = distance; return playable; } public void GatherProperties(PlayableDirector director, IPropertyCollector driver) { // 再生終了などで状態を元に戻す場合は、IPropertyPreviewを実装する var resolved = director.GetReferenceValue(transform.exposedName, out var isValid) as Transform; if (isValid) { driver.AddFromName(resolved, "m_LocalPosition.x"); driver.AddFromName(resolved, "m_LocalPosition.y"); driver.AddFromName(resolved, "m_LocalPosition.z"); driver.AddFromName(resolved, "m_LocalRotation.x"); driver.AddFromName(resolved, "m_LocalRotation.y"); driver.AddFromName(resolved, "m_LocalRotation.z"); driver.AddFromName(resolved, "m_LocalRotation.w"); } } }
ClipCaps
ClipをTimelineエディタで値に応じた編集ができるようになる。 個々の機能は別途動作するように実装しなければならない。
定義 | 説明 |
---|---|
None | すべての機能はサポートされません。 |
Looping | Playable を表すクリップはループをサポートします。 |
Extrapolation | Playable を表すクリップはクリップの補外をサポートします。 |
ClipIn | Playable を表すクリップは 0 より大きい初期ローカル時刻をサポートします。 |
SpeedMultiplier | Playable を表すクリップはタイムスケールをサポートします。 |
Blending | Playable を表すクリップはクリップ間のブレンディングをサポートします。 |
All | すべての機能がサポートされます。 |
BlendCurves
2つのクリップ間のブレンド、もしくはEaseIn/EaseOutのどちらかに使用される。 BlendInDuration/BlendOutDurationが編集できない時はブレンド、編集できる時はEaseIn/EaseOut。
CustomMixerBehaviour
public class SimpleCustomMixerBehaviour : PlayableBehaviour { private PlayableDirector director; public string Label { get; set; } public override void OnPlayableCreate(Playable playable) { // Resolver = PlayableDirector director = (playable.GetGraph().GetResolver() as PlayableDirector); } // NOTE: This function is called at runtime and edit time. Keep that in mind when setting the values of properties. public override void ProcessFrame(Playable playable, FrameData info, object playerData) { // Trackにバインディングされたデータ GameObject trackBinding = playerData as GameObject; if (!trackBinding) return; int inputCount = playable.GetInputCount(); for (int i = 0; i < inputCount; i++) { float inputWeight = playable.GetInputWeight(i); ScriptPlayable<SimpleCustomBehaviour> inputPlayable = (ScriptPlayable<SimpleCustomBehaviour>)playable.GetInput(i); SimpleCustomBehaviour input = inputPlayable.GetBehaviour(); // Use the above variables to process each frame of this playable. if (0 < inputWeight) { // 再生中のClip } } } public override void OnBehaviourPause(Playable playable, FrameData info) { // Trackで変更されたデータを元の状態に戻したりする } public override void OnGraphStop(Playable playable) { // Trackで変更されたデータを元の状態に戻したりする } public override void OnPlayableDestroy(Playable playable) { // Trackで変更されたデータを元の状態に戻したりする } }
関数 | 説明 |
---|---|
OnGraphStart | この関数は、このPlayableBehaviourを所有するPlayableGraphが起動したときに呼び出されます。 |
OnGraphStop | この関数は、このPlayableBehaviourを所有するPlayableGraphが停止したときに呼び出されます。 |
OnPlayableCreate | この関数は、PlayableBehaviourを所有するPlayableが作成されたときに呼び出されます。 |
OnPlayableDestroy | この関数は、PlayableBehaviourを所有するPlayableが破棄されたときに呼び出されます。 |
OnBehaviourPause | このメソッドは、次のいずれかの状況が発生したときに呼び出されます。トラバーサル中の有効な再生状態がPlayState.Pausedに変更された場合。この状態は、FrameData.effectivePlayStateによって示されます。PlayableGraphは、再生可能な再生状態がPlayingである間は停止します。この状態は、PlayableGraph.IsPlayingがtrueを返すことで示されます。 |
OnBehaviourPlay | この関数は、Playableの再生状態がPlayState.Playingに変更されたときに呼び出されます。 |
PrepareData | この関数は、PlayableGraphのPrepareDataフェーズで呼び出されます。 |
PrepareFrame | この関数は、PlayableGraphのPrepareFrameフェーズで呼び出されます。 |
ProcessFrame | この関数は、PlayableGraphのProcessFrameフェーズ中に呼び出されます。 |
CustomBehaviour
[Serializable] public class SimpleCustomBehaviour : PlayableBehaviour { public Transform transform; public float distance; private string Name => nameof(SimpleCustomBehaviour); public override void OnGraphStart(Playable playable) { Debug.LogFormat("{0} start: {1}", Time.frameCount, Name); } public override void OnGraphStop(Playable playable) { Debug.LogFormat("{0} stop: {1}", Time.frameCount, Name); } public override void OnBehaviourPlay(Playable playable, FrameData info) { Debug.LogFormat("{0} play: {1}", Time.frameCount, Name); } public override void OnBehaviourPause(Playable playable, FrameData info) { Debug.LogFormat("{0} pause: {1}", Time.frameCount, Name); } public override void OnPlayableCreate(Playable playable) { Debug.LogFormat("{0} create: {1}", Time.frameCount, Name); } public override void OnPlayableDestroy(Playable playable) { Debug.LogFormat("{0} destroy: {1}", Time.frameCount, Name); } public override void PrepareFrame(Playable playable, FrameData info) { Debug.LogFormat("{0} prepare: {1}", Time.frameCount, Name); } public override void ProcessFrame(Playable playable, FrameData info, object playerData) { Debug.LogFormat("{0} process: {1}", Time.frameCount, Name); // Trackにバインディングされたデータ GameObject trackBinding = playerData as GameObject; // Clipの進捗を取る var progress = (float)(playable.GetTime() / playable.GetDuration()); } }
関数 | 説明 |
---|---|
OnGraphStart | この関数は、このPlayableBehaviourを所有するPlayableGraphが起動したときに呼び出されます。 |
OnGraphStop | この関数は、このPlayableBehaviourを所有するPlayableGraphが停止したときに呼び出されます。 |
OnPlayableCreate | この関数は、PlayableBehaviourを所有するPlayableが作成されたときに呼び出されます。 |
OnPlayableDestroy | この関数は、PlayableBehaviourを所有するPlayableが破棄されたときに呼び出されます。 |
OnBehaviourPause | このメソッドは、次のいずれかの状況が発生したときに呼び出されます。トラバーサル中の有効な再生状態がPlayState.Pausedに変更された場合。この状態は、FrameData.effectivePlayStateによって示されます。PlayableGraphは、再生可能な再生状態がPlayingである間は停止します。この状態は、PlayableGraph.IsPlayingがtrueを返すことで示されます。 |
OnBehaviourPlay | この関数は、Playableの再生状態がPlayState.Playingに変更されたときに呼び出されます。 |
PrepareData | この関数は、PlayableGraphのPrepareDataフェーズで呼び出されます。 |
PrepareFrame | この関数は、PlayableGraphのPrepareFrameフェーズで呼び出されます。 |
ProcessFrame | この関数は、PlayableGraphのProcessFrameフェーズ中に呼び出されます。 |
ExposedReference<T>
Timelineはアセットであるため、Scene上のオブジェクトを直接参照できない。
PlayableDirectorではこれを解決するためにExposedReference<T>
とIExposedPropertyTable
を利用して参照関係を構築している。PlayableDirectorはIExposedPropertyTable
を実装している。
Scene上のGameObjectを参照するClipは、ExposedReference<T>
でメンバを公開する。
[Serializable] public class Sample01PlayerClip : PlayableAsset, ITimelineClipAsset { // 一部抜粋 public ExposedReference<PlayableDirector> director; public override Playable CreatePlayable(PlayableGraph graph, GameObject owner) { var playable = ScriptPlayable.Create(graph, template); Sample01PlayerBehaviour clone = playable.GetBehaviour(); clone.clipName = clipName; clone.director = director.Resolve(graph.GetResolver()); return playable; } }
ExposedReference<T>
は次のようになっている。
[Serializable] [UsedByNativeCode(Name = "ExposedReference")] public struct ExposedReference<T> where T : Object { [SerializeField] public PropertyName exposedName; [SerializeField] public Object defaultValue; public T Resolve(IExposedPropertyTable resolver) { if (resolver != null) { bool idValid; Object referenceValue = resolver.GetReferenceValue(exposedName, out idValid); if (idValid) { return referenceValue as T; } } return defaultValue as T; } }
Timeline上でClipにオブジェクトを設定すると内部でexposedNameが発行される。 PlayableDirectorの設定でExposedReferenceのnameとオブジェクトのfileIDがテーブルに保持される。 exposedNameの自動発行は融通が効かないらしいという書き込みも見られる。 実際、TimelineやHierarchyを操作していると設定していた内容の参照関係が壊れて設定欄が赤くなっていることはあった。
付録1
図表全体
付録2
PlayableDirector から辿れる情報(クラス定義や実際の値)をログに出力した結果を貼っておく。
実行時のTimelineは次の通り。
PlayableDirector
/* duration 再生可能時間(秒単位)。 extrapolationMode 再生可能期間を超えたときに時間をインクリメントする方法を制御します。 initialTime Playableが最初にプレイされたときに開始する時間。 playableAsset 再生用に再生可能オブジェクトをインスタンス化するために使用されるPlayableAsset。 playableGraph PlayableDirectorによって作成されたPlayableGraph。 playOnAwake コンポーネントが起動するとすぐに再生可能なアセットの再生が開始されるかどうか。 state コンポーネントの現在の再生状態。(読み取り専用) time コンポーネントの現在の時刻。この値は、再生中にPlayableDirector.timeUpdateModeに従ってインクリメントされます。この値を手動で変更することもできます。 timeUpdateMode 再生時に時間をインクリメントする方法を制御します。 ClearGenericBinding 参照オブジェクトのバインディングをクリアします。 ClearReferenceValue 公開された参照値をクリアします。 DeferredEvaluate PlayableDirectorに、次の更新でPlayableGraphを評価するように指示します。 Evaluate 現在再生中のPlayableを現在評価します。 GetGenericBinding 参照オブジェクトへのバインディングを返します。 GetReferenceValue ExposedReferenceバインディングを取得します。 Pause 現在実行中の再生可能ファイルの再生を一時停止します。 Play 提供されたPlayableAssetを使用してPlayableをインスタンス化し、再生を開始します。 RebindPlayableGraphOutputs PlayableGraphの各PlayableOutputを再バインドします。 RebuildGraph 既存のPlayableGraphを破棄し、新しいインスタンスを作成します。 Resume 一時停止した再生可能ファイルの再生を再開します。 SetGenericBinding PlayableBindingからの参照オブジェクトのバインディングを設定します。 SetReferenceValue ExposedReference値を設定します。 Stop 現在のPlayableの再生を停止し、対応するグラフを破棄します。 paused PlayableDirectorコンポーネントが一時停止したときに発生するイベント。 played PlayableDirectorコンポーネントの再生が開始されたときに発生するイベント。 stopped PlayableDirectorコンポーネントが停止したときに発生するイベント。 [director] name: RootDirector duration: 201.980666666666 extrapolationMode: None initialTime: 0 playableAsset: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) playableGraph: UnityEngine.Playables.PlayableGraph playOnAwake: False state: Paused time: 0 timeUpdateMode: GameTime GetGenericBinding(activationTrack): Cube (UnityEngine.GameObject) GetReferenceValue.GetReferenceValue(controlAsset.sourceGameObject.exposedName, out bool _): ChildDirector (UnityEngine.GameObject) */
playableGraph
PlayableDirector.playableGraph
型:PlayableGraph
/* Connect 2つのPlayableインスタンスを接続します。 Destroy グラフを破棄します。 DestroyOutput PlayableOutputを破棄します。 DestroyPlayable Playableを破壊します。 DestroySubgraph Playableとそのすべての入力を再帰的に破棄します。 Disconnect Playableを切断します。接続によって、PlayableGraphのトポロジとその評価方法が決まります。 Evaluate グラフ内のすべてのPlayableOutputsを評価し、グラフ内の接続されているすべてのPlayablesを更新します。 GetEditorName PlayableGraphの名前を返します。 GetOutput グラフ内の指定されたインデックスでPlayableOutputを取得します。 GetOutputByType グラフ内の指定されたインデックスで、要求されたタイプのPlayableOutputを取得します。 GetOutputCount グラフ内のPlayableOutputの数を返します。 GetOutputCountByType グラフで要求されたタイプのPlayableOutputの数を取得します。 GetPlayableCount グラフが所有するPlayableの数を返します。 GetResolver ExposedReferencesを解決するためにグラフで使用されるテーブルを返します。 GetRootPlayable 指定されたインデックスに出力接続のないPlayableを返します。 GetRootPlayableCount 出力が接続されていない、グラフが所有するPlayableの数を返します。 GetTimeUpdateMode 再生時に時間がどのようにインクリメントされるかを返します。 IsDone グラフが操作を完了したことを示します。 IsPlaying グラフが現在実行中であることを示します。 IsValid PlayableGraphがPlayableGraph.CreateGraphを使用して適切に構築され、削除されていない場合はtrueを返します。 Play グラフを再生します。 SetResolver ExposedReferencesを解決するためにグラフで使用されるテーブルを変更します。 SetTimeUpdateMode 再生時の時間の増分方法を変更します。 Stop 再生中の場合、グラフを停止します。 [playableGraph] GetEditorName: RootDirector.PlayableDirector GetOutputCount: 9 GetPlayableCount: 28 GetRootPlayableCount: 1 IsDone: False IsPlaying: False IsValid: True */
PlayableDirector.playableGraph.GetRootPlayable(0)
型:Playable
/* AddInput 新しい入力ポートを作成し、指定されたPlayableの出力ポートに接続します。 ConnectInput Playableの出力ポートを入力ポートの1つに接続します。 Destroy 現在のPlayableを破棄します。 DisconnectInput Playableの入力ポートを外します。 GetDuration Playableの継続時間を返します。 GetGraph このPlayableを所有するPlayableGraphを返します。Playableは、それを作成するために使用されたグラフでのみ使用できます。 GetInput 指定された入力ポートインデックスに接続されているPlayableを返します。 GetInputCount Playableでサポートされている入力の数を返します。 GetInputWeight 指定された入力ポートインデックスに接続されているPlayableの重みを返します。 GetLeadTime 再生可能なリードタイムを秒単位で返します。 GetOutput 指定された出力ポートインデックスに接続されているPlayableを返します。 GetOutputCount Playableでサポートされている出力の数を返します。 GetPlayState Playableの現在のPlayStateを返します。 GetPreviousTime Playableの前の現地時間を返します。 GetPropagateSetTime このPlayableの時間伝播動作を返します。 GetSpeed 現在のPlayableに適用されている速度乗数を返します。 GetTime Playableの現在の現地時間を返します。 GetTraversalMode マルチ出力再生可能の伝播モードを返します。 IsDone 再生可能オブジェクトが操作を完了したことを示すフラグを返します。 IsNull Playableがnullの場合はtrueを返し、それ以外の場合はfalseを返します。 IsValid 現在のPlayableの値を返します。 Pause Playableを一時停止するように指示します。 Play Playableの再生を開始します。 SetDone 再生可能オブジェクトが操作を完了したことを示すフラグを変更します。 SetDuration Playableの継続時間を変更します。 SetInputCount Playableでサポートされる入力の数を変更します。 SetInputWeight 現在のPlayableに接続されているPlayableの重みを変更します。 SetLeadTime 再生可能なリードタイムを秒単位で設定します。 SetOutputCount Playableでサポートされる出力の数を変更します。 SetPropagateSetTime このPlayableの時間伝播動作を変更します。 SetSpeed 現在のPlayableに適用されている速度乗数を変更します。 SetTime Playableの現在の現地時間を変更します。 SetTraversalMode マルチ出力再生可能のPrepareFrameとProcessFrameの伝播モードを設定します。 [rootPlayable] GetPlayableType: UnityEngine.Timeline.TimelinePlayable GetDuration: 201.980666666666 GetGraph: UnityEngine.Playables.PlayableGraph GetInputCount: 9 GetOutputCount: 1 GetLeadTime: 0 GetPlayState: Playing GetPreviousTime: 0 GetPropagateSetTime: True GetSpeed: 1 GetTime: 0 GetTraversalMode: Passthrough */
PlayableDirector.playableGraph.GetOutput(i)
型:PlayableOutput
/* GetPlayableOutputType: Trackと対になるPlayableOutput型 ex)ScriptPlayableOutput GetReferenceObject: Trackの実体 ex)ControlTrack GetSourceOutputPort ソースプレイアブルの出力接続インデックスを返します。 Graphの接続ポート GetSourcePlayable 再生可能なソースを返します。 GetNotificationReceivers 出力に現在登録されている通知受信者のリストを取得します。 Signal/MarkerのTrackで参照しているReceiver GetUserData 不透明なユーザーデータを返します。これは、ProcessFrameの最後の最後の引数と同じ値です。 TrackにバインドされているComponent GetWeight PlayableOutputから再生可能なソースへの接続の重みを返します。 AddNotificationReceiver 通知をリッスンする新しいレシーバーを登録します。 IsOutputNull PlayableOutputがnullの場合はtrueを返し、そうでない場合はfalseを返します。 IsOutputValid PushNotification Playableシステムを介して送信される通知をキューに入れます。 RemoveNotificationReceiver 出力のレシーバーの登録を解除します。 SetReferenceObject バインドされたオブジェクトを新しい値に設定します。出力をオブジェクトに関連付けるために使用されます(タイムラインの場合はアセットを追跡します)。 SetSourcePlayable 出力を計算する再生可能オブジェクトとサブツリーインデックスを設定します。 SetUserData 不透明なユーザーデータを設定します。これと同じデータが最後の引数としてProcessFrameに渡されます。 SetWeight PlayableOutputから再生可能なソースへの接続の重みを設定します。 [playableOutput] GetPlayableOutputType: UnityEngine.Playables.ScriptPlayableOutput GetReferenceObject: GetSourceOutputPort: 0 GetSourcePlayable: UnityEngine.Playables.Playable GetNotificationReceivers: 1 GetUserData: RootDirector (UnityEngine.PlayableDirector) GetWeight: 1 GetNotificationReceivers: RootDirector [playableOutput] GetPlayableOutputType: UnityEngine.Playables.ScriptPlayableOutput GetReferenceObject: Activation Track 1 (UnityEngine.Timeline.ActivationTrack) GetSourceOutputPort: 1 GetSourcePlayable: UnityEngine.Playables.Playable GetNotificationReceivers: 0 GetUserData: Cube (UnityEngine.GameObject) GetWeight: 1 [playableOutput] GetPlayableOutputType: UnityEngine.Animations.AnimationPlayableOutput GetReferenceObject: Animation Track 1 (UnityEngine.Timeline.AnimationTrack) GetSourceOutputPort: 2 GetSourcePlayable: UnityEngine.Playables.Playable GetNotificationReceivers: 0 GetUserData: GetWeight: 0 [playableOutput] GetPlayableOutputType: UnityEngine.Audio.AudioPlayableOutput GetReferenceObject: Audio Track 1 (UnityEngine.Timeline.AudioTrack) GetSourceOutputPort: 3 GetSourcePlayable: UnityEngine.Playables.Playable GetNotificationReceivers: 0 GetUserData: GetWeight: 1 [playableOutput] GetPlayableOutputType: UnityEngine.Playables.ScriptPlayableOutput GetReferenceObject: Control Track 1 (UnityEngine.Timeline.ControlTrack) GetSourceOutputPort: 4 GetSourcePlayable: UnityEngine.Playables.Playable GetNotificationReceivers: 0 GetUserData: GetWeight: 1 [playableOutput] GetPlayableOutputType: UnityEngine.Playables.ScriptPlayableOutput GetReferenceObject: Signal Track (UnityEngine.Timeline.SignalTrack) GetSourceOutputPort: 5 GetSourcePlayable: UnityEngine.Playables.Playable GetNotificationReceivers: 1 GetUserData: RootDirector (UnityEngine.Timeline.SignalReceiver) GetWeight: 1 GetNotificationReceivers: RootDirector [playableOutput] GetPlayableOutputType: UnityEngine.Playables.ScriptPlayableOutput GetReferenceObject: Playable Track (UnityEngine.Timeline.PlayableTrack) GetSourceOutputPort: 6 GetSourcePlayable: UnityEngine.Playables.Playable GetNotificationReceivers: 0 GetUserData: GetWeight: 1 [playableOutput] GetPlayableOutputType: UnityEngine.Playables.ScriptPlayableOutput GetReferenceObject: G1-Activation Track (UnityEngine.Timeline.ActivationTrack) GetSourceOutputPort: 7 GetSourcePlayable: UnityEngine.Playables.Playable GetNotificationReceivers: 0 GetUserData: Cube (4) (UnityEngine.GameObject) GetWeight: 1 [playableOutput] GetPlayableOutputType: UnityEngine.Animations.AnimationPlayableOutput GetReferenceObject: G1-Animation Track (UnityEngine.Timeline.AnimationTrack) GetSourceOutputPort: 8 GetSourcePlayable: UnityEngine.Playables.Playable GetNotificationReceivers: 0 GetUserData: GetWeight: 0 */
PlayableDirector.playableGraph.GetOutput(i).GetSourcePlayable()
型:Playable
/* AddInput 新しい入力ポートを作成し、指定されたPlayableの出力ポートに接続します。 ConnectInput Playableの出力ポートを入力ポートの1つに接続します。 Destroy 現在のPlayableを破棄します。 DisconnectInput Playableの入力ポートを外します。 GetDuration Playableの継続時間を返します。 GetGraph このPlayableを所有するPlayableGraphを返します。Playableは、それを作成するために使用されたグラフでのみ使用できます。 GetInput 指定された入力ポートインデックスに接続されているPlayableを返します。 GetInputCount Playableでサポートされている入力の数を返します。 GetInputWeight 指定された入力ポートインデックスに接続されているPlayableの重みを返します。 GetLeadTime 再生可能なリードタイムを秒単位で返します。 GetOutput 指定された出力ポートインデックスに接続されているPlayableを返します。 GetOutputCount Playableでサポートされている出力の数を返します。 GetPlayState Playableの現在のPlayStateを返します。 GetPreviousTime Playableの前の現地時間を返します。 GetPropagateSetTime このPlayableの時間伝播動作を返します。 GetSpeed 現在のPlayableに適用されている速度乗数を返します。 GetTime Playableの現在の現地時間を返します。 GetTraversalMode マルチ出力再生可能の伝播モードを返します。 IsDone 再生可能オブジェクトが操作を完了したことを示すフラグを返します。 IsNull Playableがnullの場合はtrueを返し、それ以外の場合はfalseを返します。 IsValid 現在のPlayableの値を返します。 Pause Playableを一時停止するように指示します。 Play Playableの再生を開始します。 SetDone 再生可能オブジェクトが操作を完了したことを示すフラグを変更します。 SetDuration Playableの継続時間を変更します。 SetInputCount Playableでサポートされる入力の数を変更します。 SetInputWeight 現在のPlayableに接続されているPlayableの重みを変更します。 SetLeadTime 再生可能なリードタイムを秒単位で設定します。 SetOutputCount Playableでサポートされる出力の数を変更します。 SetPropagateSetTime このPlayableの時間伝播動作を変更します。 SetSpeed 現在のPlayableに適用されている速度乗数を変更します。 SetTime Playableの現在の現地時間を変更します。 SetTraversalMode マルチ出力再生可能のPrepareFrameとProcessFrameの伝播モードを設定します。 // 取得するPlayableはすべて同じTimelinePlayable=RootPlayable [outputPlayables] GetPlayableType: UnityEngine.Timeline.TimelinePlayable GetDuration: 201.980666666666 GetGraph: UnityEngine.Playables.PlayableGraph GetInputCount: 9 GetInput: UnityEngine.Playables.Playable GetInputWeight: 1 GetOutputCount: 1 GetOutput: UnityEngine.Playables.Playable GetLeadTime: 0 GetPlayState: Playing GetPreviousTime: 0 GetPropagateSetTime: True GetSpeed: 1 GetTime: 0 GetTraversalMode: Passthrough */
PlayableDirector.playableGraph.GetOutput(i).GetSourcePlayable().GetInput(i)
型:Playable
/* [inputPlayable] GetPlayableType: UnityEngine.Timeline.TimeNotificationBehaviour GetDuration: 201.980666666666 GetGraph: UnityEngine.Playables.PlayableGraph GetInputCount: 0 GetOutputCount: 1 GetLeadTime: 0 GetPlayState: Playing GetPreviousTime: 0 GetPropagateSetTime: True GetSpeed: 1 GetTime: 0 GetTraversalMode: Mix [inputPlayable] GetPlayableType: UnityEngine.Timeline.ActivationMixerPlayable GetDuration: 1.79769313486232E+308 GetGraph: UnityEngine.Playables.PlayableGraph GetInputCount: 3 GetOutputCount: 1 GetLeadTime: 0 GetPlayState: Playing GetPreviousTime: 0 GetPropagateSetTime: False GetSpeed: 1 GetTime: 0 GetTraversalMode: Mix [inputPlayable] GetPlayableType: UnityEngine.Animations.AnimationLayerMixerPlayable GetDuration: 1.79769313486232E+308 GetGraph: UnityEngine.Playables.PlayableGraph GetInputCount: 1 GetOutputCount: 1 GetLeadTime: 0 GetPlayState: Playing GetPreviousTime: 0 GetPropagateSetTime: False GetSpeed: 1 GetTime: 0 GetTraversalMode: Mix [inputPlayable] GetPlayableType: UnityEngine.Audio.AudioMixerPlayable GetDuration: 1.79769313486232E+308 GetGraph: UnityEngine.Playables.PlayableGraph GetInputCount: 2 GetOutputCount: 1 GetLeadTime: 0 GetPlayState: Playing GetPreviousTime: 0 GetPropagateSetTime: False GetSpeed: 1 GetTime: 0 GetTraversalMode: Mix [inputPlayable] GetPlayableType: UnityEngine.Playables.Playable GetDuration: 1.79769313486232E+308 GetGraph: UnityEngine.Playables.PlayableGraph GetInputCount: 1 GetOutputCount: 1 GetLeadTime: 0 GetPlayState: Playing GetPreviousTime: 0 GetPropagateSetTime: False GetSpeed: 1 GetTime: 0 GetTraversalMode: Mix [inputPlayable] GetPlayableType: UnityEngine.Timeline.TimeNotificationBehaviour GetDuration: 201.980666666666 GetGraph: UnityEngine.Playables.PlayableGraph GetInputCount: 0 GetOutputCount: 1 GetLeadTime: 0 GetPlayState: Playing GetPreviousTime: 0 GetPropagateSetTime: True GetSpeed: 1 GetTime: 0 GetTraversalMode: Mix [inputPlayable] GetPlayableType: UnityEngine.Playables.Playable GetDuration: 1.79769313486232E+308 GetGraph: UnityEngine.Playables.PlayableGraph GetInputCount: 1 GetOutputCount: 1 GetLeadTime: 0 GetPlayState: Playing GetPreviousTime: 0 GetPropagateSetTime: False GetSpeed: 1 GetTime: 0 GetTraversalMode: Mix [inputPlayable] GetPlayableType: UnityEngine.Timeline.ActivationMixerPlayable GetDuration: 1.79769313486232E+308 GetGraph: UnityEngine.Playables.PlayableGraph GetInputCount: 2 GetOutputCount: 1 GetLeadTime: 0 GetPlayState: Playing GetPreviousTime: 0 GetPropagateSetTime: False GetSpeed: 1 GetTime: 0 GetTraversalMode: Mix [inputPlayable] GetPlayableType: UnityEngine.Animations.AnimationMotionXToDeltaPlayable GetDuration: 1.79769313486232E+308 GetGraph: UnityEngine.Playables.PlayableGraph GetInputCount: 1 GetOutputCount: 1 GetLeadTime: 0 GetPlayState: Playing GetPreviousTime: 0 GetPropagateSetTime: False GetSpeed: 1 GetTime: 0 GetTraversalMode: Mix */
PlayableDirector.playableGraph.GetOutput(i).GetReferenceObject()
型:Object (TrackAsset)
/* TrackAsset isEmpty このトラックにクリップが含まれているか。 isSubTrack このトラックはサブトラックか。 locked The local locked state of the track. lockedInHierarchy The locked state of a track. (Read Only) muted トラックをミュートし、作成した PlayableGraph から除外します。 outputs インスタンス化した Playable の出力の説明。 parent トラックの所有者。 Group配下の場合はGroupTrack、トップレベルの場合はTimelineAsset timelineAsset このトラックが属する TimelineAsset。 保存されているTimelineAsset CreateClip Creates a clip on the track with a custom playable asset attached, whose type is specified by T. Throws an InvalidOperationException if the specified type is not supported by the track. CreateDefaultClip トラックのデフォルトクリップを作成します。クリップのアセット種類はそのトラックを作成する TrackClipTypeAttribute に基づきます。 CreateTrackMixer トラックのクリップによって生成された Playable のブレンドに使用するミキサーを作成します。 GetChildTracks サブトラック、または、トラックに設定された子トラックのリスト。 GetClips トラックが所有するクリップのリストを返します。 TimelineClip animationClip アニメーション化したパラメーターを含む AnimationClip。 asset シリアライズ可能な IPlayableAsset への参照で、クリップの特殊性を示します。 PlayableAsset clipCaps このクリップがサポートする主な機能。 clipIn クリップの再生を開始する時刻。 duration クリップの長さ (秒)。 end クリップの終了時刻。 extrapolatedDuration 補外部分も含むクリップの長さ。 extrapolatedStart 補外部分も含むクリップの開始時刻。 hasBlendIn クリップにブレンドインがあるか。 hasBlendOut クリップに、0 以外のブレンドアウトがあるか。 hasPostExtrapolation クリップの終了時以降に補外があるか。 hasPreExtrapolation クリップの開始時以前に補外があるか。 parentTrack Returns the parent track where this clip is attached. postExtrapolationMode クリップの終了後のギャップに対する補外モード。 preExtrapolationMode クリップの開始前のギャップに対する補外モード。 start クリップの開始時刻。 timeScale クリップのタイムスケール。 // PlayableAsset //var playableAsset = clip.asset as ActivationPlayableAsset; アクセス不可 //var playableAsset = clip.asset as ControlPlayableAsset; //var playableAsset = clip.asset as AudioPlayableAsset; [track] name: Activation Track 1 start: 0 end: 6 duration: 6 muted: False mutedInHierarchy: False locked: False lockedInHierarchy: False parent: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) isSubTrack: False outputs: UnityEngine.Timeline.TrackAsset+d__70 timelineAsset: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) [clip] displayName: Active A start: 0 end: 2 duration: 2 asset: ActivationPlayableAsset (UnityEngine.Timeline.ActivationPlayableAsset) [clip] displayName: Active B start: 2 end: 4 duration: 2 asset: ActivationPlayableAsset(Clone) (UnityEngine.Timeline.ActivationPlayableAsset) [clip] displayName: Active C start: 4 end: 6 duration: 2 asset: ActivationPlayableAsset(Clone)(Clone) (UnityEngine.Timeline.ActivationPlayableAsset) [track]Animation Track 1 [track]Audio Track 1 [track]Control Track 1 [clip] displayName: Child start: 14.464 end: 19.464 duration: 5 asset: ControlPlayableAsset (UnityEngine.Timeline.ControlPlayableAsset) asset.outputs: 0 [ControlTrack-InputPlayable-0] GetPlayableType: UnityEngine.Playables.Playable GetInputCount: 2 GetOutputCount: 1 [ControlTrack-InputPlayable-0-0] GetPlayableType: UnityEngine.Timeline.ActivationControlPlayable GetInputCount: 0 GetOutputCount: 1 [ControlTrack-InputPlayable-0-1] GetPlayableType: UnityEngine.Timeline.DirectorControlPlayable GetInputCount: 0 GetOutputCount: 1 [track]Signal Track [track]Playable Track [ColorTransitionBehaviour]MySamples.Experiment.ColorTransitionBehaviour [track] name: G1-Activation Track start: 0 end: 4 duration: 4 muted: False mutedInHierarchy: False locked: False lockedInHierarchy: False parent: Group1 (UnityEngine.Timeline.GroupTrack) isSubTrack: False outputs: UnityEngine.Timeline.TrackAsset+d__70 timelineAsset: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) [clip] displayName: Active start: 0 end: 2 duration: 2 asset: ActivationPlayableAsset (UnityEngine.Timeline.ActivationPlayableAsset) [clip] displayName: Active start: 2 end: 4 duration: 2 asset: ActivationPlayableAsset(Clone) (UnityEngine.Timeline.ActivationPlayableAsset) [track]G1-Animation Track */
playableAsset
PlayableDirector.playableAsset
型:PlayableAsset (TimelineAsset)
/* name オブジェクト名 duration タイムラインの長さ (秒)。 fixedDuration durationMode を固定の (変化しない) 長さに設定するときの、タイムラインの長さ。 markerTrack TimelineヘッダーのMarkerTrack rootTrackCount タイムラインのルート階層にあるトラックの数を返します。 outputTrackCount タイムラインの出力トラックの数を返します。 outputs GetOutputTracks().Select(x => x.outputs.Select(x => x)).SelectMany(x => x) と同等 GetRootTrack 指定したインデックスのルートトラックを検索します。 GetRootTracks すべてのルートトラックのリストを取得します。 Markers、GroupTrackを含む。 GetOutputTrack 指定したインデックスから出力トラックを検索します。 GetOutputTracks タイムラインのすべての出力トラックのリストを取得します。 Markersを含む。GroupTrackは配下のTrackが展開される。 [timeline] name: ObjectRelationAnalyTimeline duration: 201.980666666666 fixedDuration: 0 markerTrack: Markers (UnityEngine.Timeline.MarkerTrack) rootTrackCount: 9 outputTrackCount: 10 outputs: Markers/Activation Track 1/Animation Track 1/Audio Track 1/Control Track 1/Signal Track/Playable Track/PlayableBehaviour Logger/G1-Activation Track/G1-Animation Track GetRootTracks: Markers/Group1/Activation Track 1/Animation Track 1/Audio Track 1/Control Track 1/Signal Track/Playable Track/PlayableBehaviour Logger GetOutputTracks: Markers/Activation Track 1/Animation Track 1/Audio Track 1/Control Track 1/Signal Track/Playable Track/PlayableBehaviour Logger/G1-Activation Track/G1-Animation Track */
PlayableDirector.playableAsset.outputs
型:IEnumerable
/* streamName 出力または入力ストリームの名前。 outputTargetType このPlayableBindingのPlayableOutputに必要なターゲットのタイプ。 TrackのTrackBindingType sourceObject このバインディングのキーとして機能するUnityEngine.Objectへの参照。 TrackAsset [binding] streamName: Markers outputTargetType: UnityEngine.GameObject sourceObject: [binding] streamName: Activation Track 1 outputTargetType: UnityEngine.GameObject sourceObject: Activation Track 1 (UnityEngine.Timeline.ActivationTrack) [binding] streamName: Animation Track 1 outputTargetType: UnityEngine.Animator sourceObject: Animation Track 1 (UnityEngine.Timeline.AnimationTrack) [binding] streamName: Audio Track 1 outputTargetType: UnityEngine.AudioSource sourceObject: Audio Track 1 (UnityEngine.Timeline.AudioTrack) [binding] streamName: Control Track 1 outputTargetType: sourceObject: Control Track 1 (UnityEngine.Timeline.ControlTrack) [binding] streamName: Signal Track outputTargetType: UnityEngine.Timeline.SignalReceiver sourceObject: Signal Track (UnityEngine.Timeline.SignalTrack) [binding] streamName: Playable Track outputTargetType: sourceObject: Playable Track (UnityEngine.Timeline.PlayableTrack) [binding] streamName: PlayableBehaviour Logger outputTargetType: sourceObject: PlayableBehaviour Logger (UnityEngine.Timeline.PlayableTrack) [binding] streamName: G1-Activation Track outputTargetType: UnityEngine.GameObject sourceObject: G1-Activation Track (UnityEngine.Timeline.ActivationTrack) [binding] streamName: G1-Animation Track outputTargetType: UnityEngine.Animator sourceObject: G1-Animation Track (UnityEngine.Timeline.AnimationTrack) */
PlayableDirector.playableAsset.GetOutputTracks()
型:TrackAsset
/* name オブジェクト名 start end duration インスタンス化されたPlayableの再生時間(秒単位)。 muted トラックをミュートし、作成した PlayableGraph から除外します。 mutedInHierarchy locked The local locked state of the track. lockedInHierarchy The locked state of a track. (Read Only) parent トラックの所有者。 TimelineAsset isEmpty このトラックにクリップが含まれているか。 isSubTrack このトラックはサブトラックか。 outputs インスタンス化した Playable の出力の説明。 PlayableBinding timelineAsset このトラックが属する TimelineAsset。 GetChildTracks サブトラック、または、トラックに設定された子トラックのリスト。 Group配下のTrackなど GetClips トラックが所有するクリップのリストを返します。 GetGroup Group配下のTrackで自分のGroupTrackを取得できる GetMarkers ヘッダーのMarkerTrack、SignalTrackで取得できる [trackAsset] name: Markers start: 11.233333333333 end: 11.233333333333 duration: 0 muted: False mutedInHierarchy: False locked: False lockedInHierarchy: False parent: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) isSubTrack: False outputs: Markers timelineAsset: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) GetMarkers: Signal Emitter/Signal Emitter/MySamples/Annotation1 [trackAsset] name: Activation Track 1 start: 0 end: 6 duration: 6 muted: False mutedInHierarchy: False locked: False lockedInHierarchy: False parent: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) isSubTrack: False outputs: Activation Track 1 timelineAsset: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) GetClips: Active A/Active B/Active C [trackAsset] name: Animation Track 1 start: 2 end: 7 duration: 5 muted: False mutedInHierarchy: False locked: False lockedInHierarchy: False parent: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) isSubTrack: False outputs: Animation Track 1 timelineAsset: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) GetClips: angry [trackAsset] name: Audio Track 1 start: 0 end: 201.980666666667 duration: 201.980666666667 muted: False mutedInHierarchy: False locked: False lockedInHierarchy: False parent: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) isSubTrack: False outputs: Audio Track 1 timelineAsset: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) GetClips: MusMus-BGM-042/jump [trackAsset] name: Control Track 1 start: 14.464 end: 19.464 duration: 5 muted: False mutedInHierarchy: False locked: False lockedInHierarchy: False parent: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) isSubTrack: False outputs: Control Track 1 timelineAsset: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) GetClips: Child [trackAsset] name: Signal Track start: 14.464 end: 14.464 duration: 0 muted: False mutedInHierarchy: False locked: False lockedInHierarchy: False parent: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) isSubTrack: False outputs: Signal Track timelineAsset: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) GetMarkers: Signal Emitter [trackAsset] name: Playable Track start: 19.464 end: 24.464 duration: 5 muted: False mutedInHierarchy: False locked: False lockedInHierarchy: False parent: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) isSubTrack: False outputs: Playable Track timelineAsset: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) GetClips: ColorTransitionClip [trackAsset] name: PlayableBehaviour Logger start: 2 end: 7 duration: 5 muted: True mutedInHierarchy: True locked: False lockedInHierarchy: False parent: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) isSubTrack: False outputs: PlayableBehaviour Logger timelineAsset: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) GetClips: SimplePlayableAsset [trackAsset] name: G1-Activation Track start: 0 end: 4 duration: 4 muted: False mutedInHierarchy: False locked: False lockedInHierarchy: False parent: Group1 (UnityEngine.Timeline.GroupTrack) isSubTrack: False outputs: G1-Activation Track timelineAsset: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) GetClips: Active/Active GetGroup: Group1 [trackAsset] name: G1-Animation Track start: 0 end: 25.55 duration: 25.55 muted: False mutedInHierarchy: False locked: False lockedInHierarchy: False parent: Group1 (UnityEngine.Timeline.GroupTrack) isSubTrack: False outputs: G1-Animation Track timelineAsset: ObjectRelationAnalyTimeline (UnityEngine.Timeline.TimelineAsset) GetClips: Idle GetGroup: Group1 */
PlayableDirector.playableAsset.GetOutputTracks().GetClips()
型:TimelineClip
/* displayName start クリップの開始時刻。 end クリップの終了時刻。 duration クリップの長さ (秒)。 asset シリアライズ可能な IPlayableAsset への参照で、クリップの特殊性を示します。 Clipを表すPlayableAsset animationClip アニメーション化したパラメーターを含む AnimationClip。 clipCaps このクリップがサポートする主な機能。 clipIn クリップの再生を開始する時刻。 extrapolatedDuration 補外部分も含むクリップの長さ。 extrapolatedStart 補外部分も含むクリップの開始時刻。 hasBlendIn クリップにブレンドインがあるか。 hasBlendOut クリップに、0 以外のブレンドアウトがあるか。 hasPostExtrapolation クリップの終了時以降に補外があるか。 hasPreExtrapolation クリップの開始時以前に補外があるか。 parentTrack Returns the parent track where this clip is attached. postExtrapolationMode クリップの終了後のギャップに対する補外モード。 preExtrapolationMode クリップの開始前のギャップに対する補外モード。 timeScale クリップのタイムスケール。 [timelineClip] displayName: Active A start: 0 end: 2 duration: 2 asset: ActivationPlayableAsset (UnityEngine.Timeline.ActivationPlayableAsset) [timelineClip] displayName: Active B start: 2 end: 4 duration: 2 asset: ActivationPlayableAsset(Clone) (UnityEngine.Timeline.ActivationPlayableAsset) [timelineClip] displayName: Active C start: 4 end: 6 duration: 2 asset: ActivationPlayableAsset(Clone)(Clone) (UnityEngine.Timeline.ActivationPlayableAsset) [timelineClip] displayName: angry start: 2 end: 7 duration: 5 asset: AnimationPlayableAsset (UnityEngine.Timeline.AnimationPlayableAsset) [timelineClip] displayName: MusMus-BGM-042 start: 0 end: 164.780408163265 duration: 164.780408163265 asset: AudioPlayableAsset (UnityEngine.Timeline.AudioPlayableAsset) [timelineClip] displayName: jump start: 194.516666666667 end: 201.980666666667 duration: 7.464 asset: AudioPlayableAsset (UnityEngine.Timeline.AudioPlayableAsset) [timelineClip] displayName: Child start: 14.464 end: 19.464 duration: 5 asset: ControlPlayableAsset (UnityEngine.Timeline.ControlPlayableAsset) [timelineClip] displayName: ColorTransitionClip start: 19.464 end: 24.464 duration: 5 asset: ColorTransitionClip (MySamples.Experiment.ColorTransitionClip) [timelineClip] displayName: SimplePlayableAsset start: 2 end: 7 duration: 5 asset: SimplePlayableAsset (MySamples.PlayableGraphs.SimplePlayableAsset) [timelineClip] displayName: Active start: 0 end: 2 duration: 2 asset: ActivationPlayableAsset (UnityEngine.Timeline.ActivationPlayableAsset) [timelineClip] displayName: Active start: 2 end: 4 duration: 2 asset: ActivationPlayableAsset(Clone) (UnityEngine.Timeline.ActivationPlayableAsset) [timelineClip] displayName: Idle start: 0 end: 25.55 duration: 25.55 asset: AnimationPlayableAsset (UnityEngine.Timeline.AnimationPlayableAsset) */
Clipの動き
エディタ再生時
Clipの振る舞いであるCustomeBehaviourにログを仕込んだ結果が次の通り。 先頭の数字は実行時のグローバルなFrame番号。
//479 create: logging //479 start: logging //479 pause: logging //687 play: logging //687 prepare: logging //687 process: logging //688 prepare: logging //688 process: logging //689 prepare: logging //689 process: logging //690 prepare: logging //690 process: logging //... //830 prepare: logging //830 process: logging //831 prepare: logging //831 process: logging //832 prepare: logging //832 process: logging //833 prepare: logging //833 process: logging //834 prepare: logging //834 process: logging //835 pause: logging //4117 stop: logging //4117 destroy: logging
PlayableDirectorのPlayメソッドを実行したのが479Frameとなる。 Clipは、PlayableDirectorがPlayされる時に生成される。Clipの範囲に再生ヘッドがない場合はすぐにPause状態になる。 再生ヘッドがClipに入るとClipがPlayになり、抜けるとPauseに戻る。 PlayableDirectorでTimelineが終了するとstop、destroyとなる。
PlayableDirectorでは、Playする時にGraphが生成され終了するとGraphが破棄される。
エディタ停止中
TimelineエディタでTimelineを開いた時に、create、start、pauseが呼ばれる。 再生ヘッドがClipに入ると、play、prepare、processが呼ばれる。(Timeline停止してても) 抜けるとpauseになる。 Timelineを再生して終了まで行くと、stop、start、pauseを繰り返す。 Clipのサイズや位置を変更すると、stop、destroy、create、start、pauseが呼ばれ、Graphが逐次再生成されているのが分かる。