なつねこメモ

主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ 書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。

Unity のカスタムシェーダー GUI で、Tiling & Offset を良い感じに表示したい

最近は Toon Shader の勉強をしている私です。
Unity のシェーダーでは C# コードで GUI を自分で組めるのですが、
Tiling と Offset に対応していると、邪魔だと感じるときがあるので、良い感じに表示するための方法。


普通に作るとこんな感じになるとおもいます。

public override void OnGUI(MaterialEditor me, MaterialProperty[] properties)
{
    me.TexturePropertySingleLine(new GUIContent("Main Texture", _MainTex, _Color);
    me.TextureScaleOffsetProperty(_MainTex);
}

f:id:MikazukiFuyuno:20210111183524p:plain

ただ、テクスチャの枚数が多くなってくると、地味に Tiling & Offset の項目が邪魔な気がしてきます。
(私は邪魔だと感じました、縦にスペースも取るし、区切りも分かりづらいので。)

ということで、良い感じに表示してみる。
こんな感じに Foldout を定義してあげて、

private static void TextureFoldout(string label, MaterialEditor me, MaterialProperty property, ref bool display)
{
    var rect = GUILayoutUtility.GetRect(16.0f, 22.0f, GUIStyle.none);
    var e = Event.current;

    me.TexturePropertyMiniThumbnail(new Rect(rect.x + 18.0f, rect.y + 2.0f, rect.width - 20.0f, rect.height), property, label, "");

    var toggle = new Rect(rect.x + 2.0f + EditorGUI.indentLevel * 16.0f, rect.y + 3.0f, 16.0f, 16.0f);
    if (e.type == EventType.Repaint)
        EditorStyles.foldout.Draw(toggle, false, false, display, false);

    if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition))
    {
        display = !display;
        e.Use();
    }

    if (display)
        using (new EditorGUI.IndentLevelScope())
            me.TextureScaleOffsetProperty(property);
}

このように使ってあげる。

// _isFoldoutMainTextureExpand はインスタンス変数として用意しておく
TextureFoldout("Main Texture", me, _MainTex, ref _isFoldoutMainTextureExpand);

そうすると、こんな感じに Foldout で開いたときだけ、 Tiling & Offset が表示されるようになります。

f:id:MikazukiFuyuno:20210111184353p:plain

参考: