US5L5——EnumDrawer和KeywordEnumDrawer

本章代码关键字

1
2
[Enum()]            // 让float属性在Inspector窗口中显示一个下拉列表
[KeywordEnum()] // 让属性在Inspector窗口中显示一个下拉列表,同时生成对应的选项关键字

EnumDrawer的使用

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

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

使用示例(基于运行时逻辑):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
Shader "TeachShader/Lesson131"
{
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 v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}

fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = fixed4(0, 0, 0, 0);
if (_TestEnum == 0)
{
col = tex2D(_MainTex, i.uv);
}
else if (_TestEnum == 1)
{
col = fixed4(1, 0, 0, 1);
}
else if (_TestEnum == 2)
{
col = fixed4(0, 1, 0, 1);
}
else
{
col = fixed4(0, 0, 1, 1);
}

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

显示效果:

image

这样,我们即可通过 TestEnum​ 动态控制材质的颜色

KeywordEnumDrawer的使用

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

使用方式:

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

当我们使用它时,会自动生成对应关键字(会变成大写) _属性名_显示名1​、_属性名_显示名2​ …
同样的在 Shader 的 CG 代码块部分使用时,需要使用 #pragma shader_feature​ 或 #pragma multi_compile​ 来生成的关键词

1
2
3
4
5
6
7
Properties
{
_MainTex("Texture", 2D) = "white"{}
// _TestKeywordEnum属性会自动生成以下关键字:
// _TESTKEYWORDENUM_TEX、_TESTKEYWORDENUM_RED、_TESTKEYWORDENUM_GREEN、_TESTKEYWORDENUM_BLUE
[KeywordEnum(Tex, Red, Green, Blue)] _TestKeywordEnum("TestEnum", Float) = 0
}
1
2
3
4
5
6
7
8
9
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
// 关联关键词
#pragma shader_feature _TESTKEYWORDENUM_TEX _TESTKEYWORDENUM_RED _TESTKEYWORDENUM_GREEN _TESTKEYWORDENUM_BLUE
// ...
ENDCG
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
fixed4 frag (v2f i) : SV_Target
{
// 使用关键词
fixed4 col = fixed4(0, 0, 0, 0);
#if defined(_TESTKEYWORDENUM_TEX)
col = tex2D(_MainTex, i.uv);
#elif defined(_TESTKEYWORDENUM_RED)
col = fixed4(1, 0, 0, 1);
#elif defined(_TESTKEYWORDENUM_GREEN)
col = fixed4(0, 1, 0, 1);
#elif defined(_TESTKEYWORDENUM_BLUE)
col = fixed4(0, 0, 1, 1);
#else
col = fixed4(0, 0, 0, 0);
#endif
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}

使用示例(基于变体):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
Shader "TeachShader/Lesson131"
{
Properties
{
_MainTex("Texture", 2D) = "white"{}
// _TestKeywordEnum属性会自动生成以下关键字:
// _TESTKEYWORDENUM_TEX、_TESTKEYWORDENUM_RED、_TESTKEYWORDENUM_GREEN、_TESTKEYWORDENUM_BLUE
[KeywordEnum(Tex, Red, Green, Blue)] _TestKeywordEnum("TestEnum", 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 _TESTKEYWORDENUM_TEX _TESTKEYWORDENUM_RED _TESTKEYWORDENUM_GREEN _TESTKEYWORDENUM_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 v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}

fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = fixed4(0, 0, 0, 0);
#if defined(_TESTKEYWORDENUM_TEX)
col = tex2D(_MainTex, i.uv);
#elif defined(_TESTKEYWORDENUM_RED)
col = fixed4(1, 0, 0, 1);
#elif defined(_TESTKEYWORDENUM_GREEN)
col = fixed4(0, 1, 0, 1);
#elif defined(_TESTKEYWORDENUM_BLUE)
col = fixed4(0, 0, 1, 1);
#else
col = fixed4(0, 0, 0, 0);
#endif
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}

显示效果:

image