【Unity】【エディタ拡張】シーンのGIの設定をチェックするツール

シーンのGIの設定をチェックするツールです。

Unity2018.2.17

課題

LightingWindowのGIの設定は意識する機会が少ないものの、
うっかり間違えているとパフォーマンスに大きな影響を及ぼします。

techblog.kayac.com

プロジェクトが大きくなってシーンが増えてくるとチェックだけでも大変なので、
GIの設定をチェックするためのツールを作りました。
エラーが生じているシーンをcsvファイルに書き出します。

また今回はGIを使わないプロジェクトのために作っていますが、
そのあたりはプロジェクトごとに書き換えていただければと思います。

ソースコード

それではソースコードです。

public static class Example
{
    [MenuItem("Tools/Check GI Settings Error")]
    private static void CheckGISettingsError()
    {
        // シーンパスを取得
        var sceneAssetPaths = AssetDatabase
            .FindAssets("t:Scene")
            .Select(x => AssetDatabase.GUIDToAssetPath(x));

        // 今のシーンのパスを取得
        var previousPath = EditorSceneManager.GetActiveScene().path;

        var output = "シーン名,エラー内容" + System.Environment.NewLine;
        var errorTexts = new List<string>();

        foreach (var scenePath in sceneAssetPaths) {
            errorTexts.Clear();

            // シーンを開く
            EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single);
            
            // エラー情報を追加
            if (Lightmapping.bakedGI)
                errorTexts.Add("BakedGIがON");
            if (Lightmapping.realtimeGI)
                errorTexts.Add("RealtimeGIがON");
            
            // エラーが無い場合はスキップ
            if (errorTexts.Count == 0) {
                continue;
            }

            // ファイル名を追加
            output += scenePath + ",";

            // エラー情報を追加
            output += errorTexts.Aggregate((a, b) => a + " / " + b);
            output += System.Environment.NewLine;
        }

        // 元のシーンを開く
        if (!string.IsNullOrEmpty(previousPath)) {
            EditorSceneManager.OpenScene(previousPath, OpenSceneMode.Single);
        }

        // 出力
        SaveTextToFile(output, "csv");
    }

    /// <summary>
    /// 文字列をファイルに上書き保存
    /// 保存先選択パネルを表示
    /// </summary>
    public static void SaveTextToFile(string text, string extension)
    {
        // 保存先のファイルパスを取得する
        var filePath = EditorUtility.SaveFilePanel("Save", "Assets", "filename", extension);

        // パスが入っていれば選択されたということ(キャンセルされたら入ってこない)
        if (!string.IsNullOrEmpty(filePath)) {
            // 上書き保存
            SaveTextToFile(text, filePath, false);
        }
    }
    
    /// <summary>
    /// 文字列をファイルに保存
    /// </summary>
    public static void SaveTextToFile(string text, string filePath, bool append = false)
    {
        // ファイルに文字列を書き込む
        var sw = new StreamWriter(filePath, append);
        sw.WriteLine(text);
        sw.Flush();
        sw.Close();

        // アセットだったらRefresh
        if (filePath.Contains(Application.dataPath)) {
            AssetDatabase.Refresh();
        }
    }
}

説明はコメントを参照してください。

重いよ > Pythonで書いた

上記の処理はSceneを一個一個開いていくのでSceneが増えると時間が掛かります。
直接シリアライズされている文字列を検索した方がいいですね。。

まあそんなに頻繁にやることでもないと思うので今回はこれで。
機会があったらpythonあたりで書こうと思います。

2019/4/2追記
Pythonで書きました(チェックツールではなく無効化ツールですが)

light11.hatenadiary.com

出力結果

こんな感じのcsvファイルが出力されます。

シーン名,エラー内容
Assets/Example1.unity,BakedGIがON / RealtimeGIがON
Assets/Example2.unity,BakedGIがON
Assets/Example3.unity,RealtimeGIがON

自動化しよう

本来であればこのあたりの設定はSceneを作った時に自動化されているのが望ましいです。
これはAssetPostprocessorを使えば実現できます。

下記の記事にまとめているのでそちらを参照してください。

light11.hatenadiary.com

関連

light11.hatenadiary.com

参考サイト

techblog.kayac.com

https://forum.unity.com/threads/access-lighting-window-properties-in-script.328342/