【Unity】【シェーダ】【エディタ拡張】マテリアルのインスペクタ拡張まとめ

f:id:halya_11:20180830142636p:plain

マテリアルのインスペクタを拡張する方法と、よく使うプロパティ描画方法などをまとめました。

ソースコード

マテリアルのインスペクタを拡張するにはShaderGUIを継承したクラスを作ります。

using UnityEngine;
using UnityEditor;
using System.Linq;

// ShaderGUIを継承したクラスを作る
public class ExampleShaderGUI : ShaderGUI {

    private int _exampleInt       = 0;

    public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
    {
        // プロパティを取得
        var exampleTexProp          = FindProperty("_ExampleTex", properties);
        var exampleTintProp         = FindProperty("_ExampleTint", properties);
        var exampleHDRColorProp     = FindProperty("_ExampleHDRColor", properties);

        // マテリアルのインスタンスを取得
        // 複数選択時には複数入ってくる
        var materials           = materialEditor.targets.Cast<Material>();

        // ラベル(太字)
        // GUILayout / EditorGUILayoutにあるものは使える
        GUILayout.Label("Label", EditorStyles.boldLabel);
        EditorGUILayout.Space();

        // テクスチャ
        materialEditor.TextureProperty(exampleTexProp, "テクスチャ");
        EditorGUILayout.Space();

        // テクスチャ(1行表示)
        materialEditor.TexturePropertySingleLine(new GUIContent("テクスチャ(1行表示)"), exampleTexProp);

        // テクスチャのスケールとオフセット
        using (new EditorGUI.IndentLevelScope()) {
            materialEditor.TextureScaleOffsetProperty(exampleTexProp);
            EditorGUILayout.Space();
        }

        // テクスチャとTintを一行に表示
        materialEditor.TexturePropertySingleLine(new GUIContent("テクスチャとColor"), exampleTexProp, exampleTintProp);
        EditorGUILayout.Space();

        // HDRカラーとテクスチャ
        materialEditor.TexturePropertyWithHDRColor(new GUIContent("テクスチャとHDRColor"), exampleTexProp, exampleHDRColorProp, new ColorPickerHDRConfig(0, 100, 0.01f, 3.0f), false);

        // キーワードを有効化/無効化/有効チェック
        // キーワードはすべてのtargetに適用しないと複数選択時にすべてに適用されない
        foreach (Material material in materialEditor.targets) {
            material.EnableKeyword("TEST");
            material.DisableKeyword("TEST");
            var keywordEnabled  = material.IsKeywordEnabled("TEST");
        }
        EditorGUILayout.Space();


        // キーワードの有効化/無効化はUndoの対象にならないので手動でUndo対応したほうがいい
        using (var changeCheckScope = new EditorGUI.ChangeCheckScope()) {

            // Keywordを有効化するかどうか決める処理
            var isKeywordEnabled            = true;

            if (changeCheckScope.changed) {
                // まずRecordしておく
                materialEditor.RegisterPropertyChangeUndo("Example Keyword");

                // そのあとにKeywordを変える
                if (isKeywordEnabled) {
                    foreach (Material material in materialEditor.targets) {
                        material.EnableKeyword("TEST");
                    }
                }
                else {
                    foreach (Material material in materialEditor.targets) {
                        material.DisableKeyword("TEST");
                    }
                }
            }
        }
        
    }
}

このクラス名をシェーダ側にCustomEditorとして記述することで、インスペクタの表示が変わります。

docs.unity3d.com

結果

上記のソースコードによりインスペクタは次のように拡張されます。

f:id:halya_11:20180830142636p:plain