材质着色器属性
在过场动画时,可能需要动态修改材质属性的事件,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来获得材质的所有属性。接着,将所有的属性描述列出来,让用户选择即可。