夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

Unityプロジェクト内のマテリアルをシェーダー別に取得するツールを作る その②ボタンの実装とマテリアルの検索

本日はUnity枠です。

昨日からMRGT向けの新機能としてUnityプロジェクト内のマテリアルをシェーダー別に取得するツールを作成しています。

前回はエディタウィンドウの基本設定を行っていきました。

redhologerbera.hatenablog.com

今回はこちらの機能を作成していきます。

〇ボタンの配置と処理の実行

OnGUI関数内でif文でGUILayout.Button(ボタン名)を記述することでボタンが表示されます。

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


public class MaterialSearcher : EditorWindow
{
    [MenuItem("Window/Graphics Tools/Material Search by Shader")]
    static void MaterialSearch()
    {
        // OpenEditorWindow
        GetWindow<MaterialSearcher>();
    }

   //ウィンドウのUI
    void OnGUI()
    {
        //Searchという名前のボタンを表示
        if (GUILayout.Button("Search"))
        {
         //ボタンを押した際に実行される関数
          ProcessComponentsInAllScenes();
        }
    }
    
    private void ProcessComponentsInAllScenes()
    {
        Debug.Log("Action");
    }
}

これによりウィンドウにSearchボタンが出現します。

ボタンを押すことでProcessComponentsInAllScenesが実行されデバッグログが出力されます。

〇全シーンからマテリアルを検出する

今回はプロジェクト全体の全シーンからマテリアルを取得します。

この手法自体は以下のブログを参考にしています。

unity-yuji.xyz

   private void ProcessComponentsInAllScenes()
    {
        var list = AssetDatabase.FindAssets("t:Material")
                .Select(AssetDatabase.GUIDToAssetPath).Select(c => AssetDatabase.LoadAssetAtPath<Material>(c))
                .Where(c => c != null);
            
                foreach (var n in list)
                {
                    Debug.Log(n.shader.name);
                }
    }

AssetDatabase.FindAssetsはその名の通りプロジェクトから指定したタイプのアセットを検索します。

docs.unity3d.com

全データをlistに格納し foreach文でログとして出力しています。

これによって全マテリアルを取得できました。

次回はこのマテリアルからシェーダーごとにふるいにかけていきます。

〇ソースコード

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


public class MaterialSearcher : EditorWindow
{
    [MenuItem("Window/Graphics Tools/Material Search by Shader")]
    static void MaterialSearch()
    {
        // OpenEditorWindow
        GetWindow<MaterialSearcher>();
    }

    void OnGUI()
    {
        if (GUILayout.Button("Search"))
        {
            ProcessComponentsInAllScenes();
        }
    }

    private void ProcessComponentsInAllScenes()
    {
        var list = AssetDatabase.FindAssets("t:Material")
                .Select(AssetDatabase.GUIDToAssetPath).Select(c => AssetDatabase.LoadAssetAtPath<Material>(c))
                .Where(c => c != null);
            
                foreach (var n in list)
                {
                    Debug.Log(n.shader.name);
                }
    }
}