Unity如何设置材质属性
发表于2017-08-04
材质着色器属性

本篇文章会和大家介绍如何设置材质属性,在过场动画时,可能需要动态修改材质属性的事件,Unity 的材质Material通过SetColor、SetVector等接口来更改设置其属性值。在编辑器代码中,有个MaterialProperty公开类,作为材质属性设置和获取的接口。
它将材质属性类型分为5种:
public enum PropType { Color, Vector, Float, Range, Texture }
将纹理类型分为3种:
public enum TexDim { Unknown = -1, None, Tex2D = 2, Tex3D, Cube, Any = 6 }
可获取和设置值包括colorValue、floatValue、vectorValue 和 textureValue,那么设计更改材质属性事件也可按此来设计。
材质属性更改事件
对事件的物体,做材质属性的修改。
using System; using UnityEngine; namespace CinemaDirector { [CutsceneItemAttribute("Material", "Set Material Propery", CutsceneItemGenre.ActorItem)] public class SetMaterialProperyEvent : CinemaActorEvent { public enum PropType { Color, Vector, Float, Range, Texture } [Flags] public enum TextureModifyType { Texture = 1, TextureOffset = 2, TextureScale = 4 } public string shaderName = String.Empty; public PropType propType = PropType.Texture; public string propName = "_MainTex"; public Color colorValue; public Vector4 vectorValue; public float floatValue; public Texture textureValue; public int textureModifyType = (int)TextureModifyType.Texture; public Vector2 textureOffsetValue; public Vector2 textureScaleValue = Vector2.one; public override void Trigger(GameObject Actor) { if (!Application.isPlaying || string.IsNullOrEmpty(propName) || !Actor) { return; } Renderer[] mrs = Actor.GetComponentsInChildren<Renderer>(); foreach (var mr in mrs) { ModifyMaterialProp(mr); } } private void ModifyMaterialProp(Renderer mr) { if (!mr) { return; } Material mat = mr.material; if (!mat || !mat.shader) { return; } if (mat.shader.name != shaderName) { return; } switch (propType) { case PropType.Color: mat.SetColor(propName, colorValue); break; case PropType.Vector: mat.SetVector(propName, vectorValue); break; case PropType.Float: case PropType.Range: mat.SetFloat(propName, floatValue); break; case PropType.Texture: if (((TextureModifyType)textureModifyType & TextureModifyType.Texture) != 0) { mat.SetTexture(propName, textureValue); } if (((TextureModifyType)textureModifyType & TextureModifyType.TextureOffset) != 0) { mat.SetTextureOffset(propName, textureOffsetValue); } if (((TextureModifyType)textureModifyType & TextureModifyType.TextureScale) != 0) { mat.SetTextureScale(propName, textureScaleValue); } break; } } } }
SetMaterialProperyEvent 的检视器设计
虽然SetMaterialProperyEvent脚本可以达到运行时修改材质属性,但是在编辑时,需要手动去查看此时材质所拥有的属性,是比较麻烦的。可以做个编辑器类,自动获取当前所有可更改的材质属性,让用户去选择。

新建SetMaterialProperyEventInspector脚本,在OnEnable的时候,通过MaterialEditor.GetMaterialProperties来获得材质的所有属性。接着,将所有的属性描述列出来,让用户选择即可。