現在Timeline関連の実装をしているのですが、Trackの順序をスクリプトから入れ替えたくなったのでメモ
多分こんなことしたい人いないと思うので需要ゼロです
入れ替えたい理由はPlayableOutputの接続順をプログラム的に変えたかったためです
本来はWindow内でTrackを掴むことで順番を入れ替えられます
このTrackを保持しているのはPlayableDirectorに指定しているTimelineAssetですが、このTimelineAssetにはMoveが用意されていません
悲しいことにCreateTrackとDeleteTrackしかなく、TimelineWindowの実装を追っていくと内部でMove的なメソッドは存在していますが呼び出しやすい感じにはなっていません…
そこでTrackを入れ替えたときのTimelineAssetの差分を見てみると `List
なので無理やりSerializedPropertyから書き換えることで入れ替えがうまくいきました。
var so = new SerializedObject(timelineAsset); var tracks = so.FindProperty("m_Tracks"); tracks.MoveArrayElement(src, dst); so.ApplyModifiedProperties(); so.Dispose();
これだけだとTimelineWindowの描画が更新されないのでReflectionでTimelineAssetを再読み込みするメソッドを呼び出します
第4引数のboolをtrueにしておくことで実質Reload状態にすることが出来ました
var timelineWindowType = typeof(UnityEditor.Timeline.TimelineEditor).Assembly.GetType("UnityEditor.Timeline.TimelineWindow"); var window = EditorWindow.GetWindow(timelineWindowType); var method = timelineWindowType.GetMethod("SetCurrentTimeline", BindingFlags.Instance | BindingFlags.NonPublic, null, new[] {typeof(TimelineAsset), typeof(PlayableDirector), typeof(TimelineClip), typeof(bool)}, null); method?.Invoke(window, new[] {timelineAsset, _director, (object) null, true}); <||