5.EnumDrawer和KeywordEnumDrawer

5.自定义材质面板-自带Shader材质属性绘制类-EnumDrawer和KeywordEnumDrawer


5.1 知识点

EnumDrawer的使用

EnumDrawer 是 Unity 自带的继承自 MaterialPropertyDrawer(材质属性绘制器)的类。
使用它修饰属性,可以让该属性在 Inspector 窗口中显示一个下拉列表,供用户选择。

使用方式为,在属性前添加 [Enum(显示名1, 值1, 显示名2, 值2, ...)] 修饰符,格式如下:

[Enum(显示名1, 值1, 显示名2, 值2, ...)] 属性名("显示名称", Float) = 默认值

声明 Shader 和枚举属性

Shader "Unlit/Lesson05_EnumDrawerAndeKeywordEnumDrawer"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}

        // 声明枚举,一个枚举对应一个值
        [Enum(Tex, 0, Red, 1, Green, 2, Blue, 3)]_TestEnum("TestEnum", Float) = 0
    }
    SubShader
    {
        Tags
        {
            "RenderType"="Opaque"
        }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            // 枚举映射
            fixed _TestEnum;

            v2f vert(appdata appdata)
            {
                v2f v2f;
                v2f.vertex = UnityObjectToClipPos(appdata.vertex);
                v2f.uv = TRANSFORM_TEX(appdata.uv, _MainTex);
                UNITY_TRANSFER_FOG(v2f, v2f.vertex);
                return v2f;
            }

            fixed4 frag(v2f v2f) : SV_Target
            {
                // sample the texture
                fixed4 col = fixed4(0, 0, 0, 0);

                // 条件分支语句,根据枚举值选择不同颜色
                if (_TestEnum == 0)
                    col = tex2D(_MainTex, v2f.uv);
                else if (_TestEnum == 1)
                    col = fixed4(1, 0, 0, 1);
                else if (_TestEnum == 2)
                    col = fixed4(0, 1, 0, 1);
                else if (_TestEnum == 3)
                    col = fixed4(0, 0, 1, 1);

                // apply fog
                UNITY_APPLY_FOG(v2f.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

查看效果

可以看到编辑器出现了下拉框,并且可以切换颜色。

KeywordEnumDrawer的使用

KeywordEnumDrawer 同样是 Unity 自带的继承自 MaterialPropertyDrawer(材质属性绘制器)的类,主要用于和关键词建立联系。

使用方式为,在属性前添加 [KeywordEnum(显示名1, 显示名2, ...)] 修饰符,格式如下:

[KeywordEnum(显示名1, 显示名2, ...)] 属性名("显示名称", Float) = 0

使用该修饰符后,会自动生成对应的关键字,如:
_属性名_显示名1_属性名_显示名2 等。

声明关键字枚举属性,并在片元着色器中构造变体分支语句

Shader "Unlit/Lesson05_EnumDrawerAndeKeywordEnumDrawer"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white"

        // 声明枚举后默认生成关键字:
        // _KEYWORDTESTENUM_TEX
        // _KEYWORDTESTENUM_RED
        // _KEYWORDTESTENUM_GREEN
        // _KEYWORDTESTENUM_BLUE
        [KeywordEnum(Tex, Red, Green, Blue)]_KeywordTestEnum("KeywordTestEnum", Float) = 0
    }
    SubShader
    {
        Tags
        {
            "RenderType"="Opaque"
        }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            // 声明关键字枚举
            #pragma shader_feature _KEYWORDTESTENUM_TEX _KEYWORDTESTENUM_RED _KEYWORDTESTENUM_GREEN _KEYWORDTESTENUM_BLUE

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            // 枚举映射
            fixed _TestEnum;

            v2f vert(appdata appdata)
            {
                v2f v2f;
                v2f.vertex = UnityObjectToClipPos(appdata.vertex);
                v2f.uv = TRANSFORM_TEX(appdata.uv, _MainTex);
                UNITY_TRANSFER_FOG(v2f, v2f.vertex);
                return v2f;
            }

            fixed4 frag(v2f v2f) : SV_Target
            {
                // sample the texture
                fixed4 col = fixed4(0, 0, 0, 0);

                // 条件分支语句(已注释掉)
//              if (_TestEnum == 0)
//                  col = tex2D(_MainTex, v2f.uv);
//              else if (_TestEnum == 1)
//                  col = fixed4(1, 0, 0, 1);
//              else if (_TestEnum == 2)
//                  col = fixed4(0, 1, 0, 1);
//              else if (_TestEnum == 3)
//                  col = fixed4(0, 0, 1, 1);

                // 变体分支语句,根据关键字选择不同分支
                #if defined(_KEYWORDTESTENUM_TEX)
                    col = tex2D(_MainTex, v2f.uv);
                #elif defined(_KEYWORDTESTENUM_RED)
                    col = fixed4(1,0,0,1);
                #elif defined(_KEYWORDTESTENUM_GREEN)
                    col = fixed4(0,1,0,1);
                #elif defined(_KEYWORDTESTENUM_BLUE)
                    col = fixed4(0,0,1,1);
                #else
                    col = fixed4(0,0,0,0);
                #endif

                // apply fog
                UNITY_APPLY_FOG(v2f.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

查看效果

编辑器同样出现了下拉框,并且可以切换颜色。


5.2 知识点代码

Lesson05_EnumDrawerAndeKeywordEnumDrawer.shader

Shader "Unlit/Lesson05_EnumDrawerAndeKeywordEnumDrawer"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}


        //声明枚举 一个枚举对应一个值
        //[Enum(Tex, 0, Red, 1, Green, 2, Blue, 3)]_TestEnum("TestEnum", Float) = 0


        //声明后默认就存在关键字
        //_KEYWORDTESTENUM_TEX
        //_KEYWORDTESTENUM_RED
        //_KEYWORDTESTENUM_GREEN
        //_KEYWORDTESTENUM_BLUE
        [KeywordEnum(Tex, Red, Green, Blue)]_KeywordTestEnum("KeywordTestEnum", Float) = 0
    }
    SubShader
    {
        Tags
        {
            "RenderType"="Opaque"
        }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            // 声明关键字枚举
            #pragma shader_feature _KEYWORDTESTENUM_TEX _KEYWORDTESTENUM_RED _KEYWORDTESTENUM_GREEN _KEYWORDTESTENUM_BLUE

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            //枚举映射
            fixed _TestEnum;

            v2f vert(appdata appdata)
            {
                v2f v2f;
                v2f.vertex = UnityObjectToClipPos(appdata.vertex);
                v2f.uv = TRANSFORM_TEX(appdata.uv, _MainTex);
                UNITY_TRANSFER_FOG(v2f, v2f.vertex);
                return v2f;
            }

            fixed4 frag(v2f v2f) : SV_Target
            {
                // sample the texture
                fixed4 col = fixed4(0, 0, 0, 0);

                //条件分支语句
                // if (_TestEnum == 0)
                //     col = tex2D(_MainTex, v2f.uv);
                // else if (_TestEnum == 1)
                //     col = fixed4(1, 0, 0, 1);
                // else if (_TestEnum == 2)
                //     col = fixed4(0, 1, 0, 1);
                // else if (_TestEnum == 3)
                //     col = fixed4(0, 0, 1, 1);

                //变体分支语句
                #if defined(_KEYWORDTESTENUM_TEX)
                col = tex2D(_MainTex, v2f.uv);
                #elif defined(_KEYWORDTESTENUM_RED)
                    col = fixed4(1,0,0,1);
                #elif defined(_KEYWORDTESTENUM_GREEN)
                    col = fixed4(0,1,0,1);
                #elif defined(_KEYWORDTESTENUM_BLUE)
                    col = fixed4(0,0,1,1);
                #else
                    col = fixed4(0,0,0,0);
                #endif

                // apply fog
                UNITY_APPLY_FOG(v2f.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

Lesson05_自定义材质面板_自带Shader材质属性绘制类_EnumDrawer和KeywordEnumDrawer.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson05_自定义材质面板_自带Shader材质属性绘制类_EnumDrawer和KeywordEnumDrawer : MonoBehaviour
{
    void Start()
    {
        #region 知识点一 EnumDrawer的使用

        //作用:
        //EnumDrawer是Unity自带的继承自MaterialPropertyDrawer(材质属性绘制器) 的类
        //使用它修饰属性,可以让该属性在Inspector窗口中显示一个下拉列表,供用户选择

        //使用方式:
        //[Enum(显示名1, 值1, 显示名2, 值2, ...)] 属性名("显示名称", Float) = 默认值

        #endregion

        #region 知识点二 KeywordEnumDrawer的使用

        //作用:
        //KeywordEnumDrawer同样是Unity自带的继承自MaterialPropertyDrawer(材质属性绘制器) 的类
        //主要使用它和关键词建立联系

        //使用方式:
        //[KeywordEnum(显示名1, 显示名2 ...)] 属性名("显示名称", Float) = 0
        //当我们使用它是,会自动生成对应关键字
        //_属性名_显示名1、_属性名_显示名2 ....

        #endregion
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏