Unity3D之Shader自定义编辑器功能拓展
发表于2016-03-23
一、前言
最近在开发一个关卡类的游戏,在导入一些3D物体的时候,发现很多时候同一个3D物体需要渲染的方式不一样,比如这颗树要双面渲染(Cull Off),但在很多情况下是可以剔除背面(Cull Back)的,之前在写Shader方面找不到什么好方法直接控制,干脆就写了两个Shader,这就造成了无谓的浪费跟资源管理的麻烦了,我们是可以更加方便地控制Shader的某些属性的。
二、正文
先看看我们最终的效果图:

这里我只是列了一部分的属性作为例子进行介绍,大家当然是可以拓展到想要控制的另外属性上面的。贴上我们需要的shader代码:

好了,让我们来分析一下具体代码的作用。
1、下拉框:

这一句简单来说就是定义了一个Float类型名字为_CullMode的变量。
[Space(10)] : 这个是指在面板上留10单位的空间展示此属性。
[Enum(CullMode)] : 这里就表明了这个变量是属于CullMode的枚举变量,在最后的默认值为0,就是CullMode.Off这个值。我们就可以根据这个枚举来进行渲染剔除类型的控制。而对应的代码是:
。然后如果我们打算用脚本去控制这个值,可以这样做:


特别要注意的是,有时候我们虽然定义了,发现所可以选择的枚举值并不是我们想要的,那就很可能是有同名的系统枚举类型了,所以我们很多时候都尽量定义全枚举变量的引用,像这样子做:

2、自定义的枚举下拉框
那我们是否可以使用自定义的枚举类型呢?以下就是例子

这样我们就定义了包含了{Original,Black,White}的枚举类型了,然后我们还有在CG语言里面定义相关联的关键字,它的形式是“变量名”+“_”+“枚举变量名”:

当我们要使用这几个关键字的时候,就是这样的:

这里的代码都是为了简单举例进行展示使用方式而已。同时,我们可以用脚本去控制宏,这个跟之前的系统定义的枚举变量控制是不一样的:

因为在定义这些自定义的枚举的时候,已经生成了Shader内部的一个对应的关键字了,所以我们必须要用EnableKeyWord/DisableKeyWord的方式去启用或者关闭。
3、选择框
当我们需要定义一个布尔型的属性的时候,我们也是可以用Float去替代的:

所使用的方式是:

而平时的常规写法是这样的:

但我们定义了这个[Toggle]之后,就可以得到一个“变量名”+“_ON”的关键字可以使用了。同样地,我们用脚本控制的时候也是一样的方式:

4、滑动条
而当我们需要去控制一个值在一个范围内的时候,我们可以使用滑动条的定义:

其实如果你不用前面的定义也是可以的,只要用Range这个定义就可以了,而脚本控制的方式也是跟SetFloat的方法是一样的。
5、隐藏显示变量
有时候定义太多东西到面板上反而会造成策划或者别的人看的时候迷糊,所以有些定义的变量,我们不想它显示在面板的时候,可以这样子做:

但其实[HideInInspector]这个变量属性也可以用在脚本上定义的,这里就不详说了。这里先写这些了,有什么意见或者建议都可以在下面留言,谢谢大家。
后续:如果大家对这些功能还不满足的话,还可以自己写编辑器,只要继承“ShaderGUI”这个类就好了,具体大家可以在这里查看:http://docs.unity3d.com/ScriptReference/ShaderGUI.html,如果有需要,我也可以继续写这个类详细的扩展。