Playable DirectorのUnusedを一気に削除するEditor拡張

2022/05/05に公開

忙しい人のためのソースコード

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Playables;

public class DeleteUnused : EditorWindow
{
    [MenuItem("GameObject/Tools/Timeline/Unusedを消去",false,1)]
    static void Delete()
    {
        // シーン上で選択中のGameObjectのPlayableAssetを取得する
        GameObject[] gameObjects = Selection.gameObjects;
        foreach (var obj in gameObjects)
        {
            try
            {
		// 現在Playableに設定されてるTimelineAssetを取得する
                var pd = obj.GetComponent<PlayableDirector>();
                var asset = pd.playableAsset;
                var path = AssetDatabase.GetAssetPath(asset);
                // シリアライズ化
                var so = new SerializedObject(pd);
                so.Update();

                // m_SceneBindingsの変数を取得
                var prop = so.FindProperty("m_SceneBindings");

                for (int i = 0; i < prop.arraySize; i++)
                {
                    // m_SceneBindingsの配列のi番目のkeyのプロパティを取得
                    var key = prop.GetArrayElementAtIndex(i).FindPropertyRelative("key");
                    // keyの参照しているオブジェクトのインスタンスIDを取得
                    var tmp = key.objectReferenceInstanceIDValue;
                    // インスタンスIDを元にアセットのパスを取得する
                    var propPath = AssetDatabase.GetAssetPath(tmp);

		  // 現在シーンに設定されてるTimelineAssetと比較して一致しなければ配列から消す
                    if (path != propPath)
                    {
                        prop.DeleteArrayElementAtIndex(i);
                        i--;
                    }
                }
		
                so.ApplyModifiedProperties();
            }
            catch(System.Exception e)
            {
                Debug.Log(e);
            }
        }
        // フィードバックないと分かり辛いから完了したらログなどで教えてあげよう
        Debug.Log("完了");
    }
}

使い方

Scene上にあるPlayableDirectorのあるGameObjectを選択した状態で右クリックをして
Tools>Timeline>Unusedを削除する を選択する。

Playable Directorの前説

まず初めにPlayable DirectorはProject上にあるTimelineAssetならびにAnimation ClipやAudio Clip等その他AssetとScene上にあるGameObjectを紐づけする事で
任意のGameObjectに対してフレーム(または秒)単位で指定の動作をさせる事が出来る

その際、シーンのGameObjectと紐付けされた情報はTimelineAsset自体ではなく
Sceneのファイルの方に保存されている。シーン上にあるGameObjectの一意性の情報はSceneファイルにしかないから仕方ないね。
なのでよくある「Timelineを複製したらGameObjectの参照が剥がれた!!」と驚く人がいるけれど、そもそもTimelineAssetにはGameObjectの情報は保存されてないのだから、剥がれたのではなく知らないが正しい。

Unusedがどのようにして発生するのか

何でだかよく分からないけれどGameObjectをBindingした設定は、Playable DirectorのTimelineAssetを別のものに差し替えると、差し替え前のBindingの設定を保持したままにしている、本当よく分からん。
Show Unusedのチェックボックスが突然生えてくるのでチェックを入れると以前の設定を見る事が出来る(これいる?)

人力だと要らないTimeline Assetを選択して「-ボタン」を押してあげれば簡単に消すことが出来る

が役割毎に複数のTimelineAssetを作っていたり多量にキャラクターを表示して動かしたりエフェクト付けたり、○○○_ver1.playableとかで諸々差し替えが増えたり、多量にリソース作るために土台となるシーンやTimelineAssetを複製して工数削減とかしていると一々コンポーネント開いてポチポチ消すのが面倒臭くなってくるので

Editor拡張でパパッと消すと楽になるよねと言うツール

Unusedを消さないでおくとどうなるの?

不要なBinding設定分シーンファイルの容量が増え続ける

消さないままシーンを複製すると雪だるま式に膨れていく

Assetbundleで不要分も読み込んでしまう

まとめ

小規模の開発だとあまり使う機会はない

大きい規模の開発だと不要な読み込み分、重くなるからツール使ってこまめに消しておこうね

Discussion