您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
201 行
5.9 KiB
201 行
5.9 KiB
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public enum ShaderPropertyType
|
|
{
|
|
Color = 0,
|
|
Vector = 1,
|
|
Float = 2,
|
|
Range = 3,
|
|
TexEnv = 4
|
|
}
|
|
|
|
[ExecuteInEditMode]
|
|
public class MaterialPropertyOverride : MonoBehaviour
|
|
{
|
|
[System.Serializable]
|
|
public class ShaderPropertyValue
|
|
{
|
|
|
|
public string propertyName;
|
|
public ShaderPropertyType type;
|
|
public Color colValue;
|
|
public Vector4 vecValue;
|
|
public float floatValue;
|
|
public Texture texValue;
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class MaterialOverride
|
|
{
|
|
public bool active;
|
|
[System.NonSerialized]
|
|
public bool showAll;
|
|
public Material material;
|
|
public MaterialPropertyOverrideAsset propertyOverrideAsset = null;
|
|
public List<ShaderPropertyValue> propertyOverrides = new List<ShaderPropertyValue>();
|
|
}
|
|
|
|
public List<MaterialOverride> materialOverrides = new List<MaterialOverride>();
|
|
|
|
// List of renderers we are affecting
|
|
public List<Renderer> m_Renderers = new List<Renderer>();
|
|
|
|
// List of materials we want to touch
|
|
public List<Material> m_Materials = new List<Material>();
|
|
|
|
private void OnEnable()
|
|
{
|
|
Apply();
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
private void OnValidate()
|
|
{
|
|
Clear();
|
|
Apply();
|
|
}
|
|
|
|
// Try to do something reasonable when component is added
|
|
private void Reset()
|
|
{
|
|
Clear();
|
|
m_Renderers.Clear();
|
|
m_Renderers.AddRange(GetComponents<Renderer>());
|
|
if (m_Renderers.Count == 0)
|
|
{
|
|
// Fall back, try LODGroup
|
|
var lg = GetComponent<LODGroup>();
|
|
if (lg != null)
|
|
{
|
|
foreach (var l in lg.GetLODs())
|
|
m_Renderers.AddRange(l.renderers);
|
|
}
|
|
}
|
|
Apply();
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
foreach (var r in m_Renderers)
|
|
{
|
|
if (r == null)
|
|
continue;
|
|
r.SetPropertyBlock(null);
|
|
for (int i = 0, c = r.sharedMaterials.Length; i < c; i++)
|
|
{
|
|
r.SetPropertyBlock(null, i);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
public void Populate()
|
|
{
|
|
m_Renderers.Clear();
|
|
var childRenderers = GetComponentsInChildren<Renderer>();
|
|
if (childRenderers.Length > 100)
|
|
{
|
|
Debug.LogError("Too many renderers.");
|
|
return;
|
|
}
|
|
m_Renderers.AddRange(childRenderers);
|
|
}
|
|
|
|
public void Apply()
|
|
{
|
|
// Apply overrides
|
|
MaterialPropertyBlock mpb = new MaterialPropertyBlock();
|
|
foreach (var renderer in m_Renderers)
|
|
{
|
|
// Can happen when you are editing the list
|
|
if (renderer == null)
|
|
continue;
|
|
|
|
if (renderer.sharedMaterials.Length == 0)
|
|
continue;
|
|
|
|
// Two cases.
|
|
// A) there are only one type of material on this renderer. Then we
|
|
// can use the master material property block.
|
|
// B) different materials; then we use the per material property blocks
|
|
|
|
bool allSame = true;
|
|
|
|
// Check if multiple materials on this renderer
|
|
for (int i = 1, c = renderer.sharedMaterials.Length; i < c; i++)
|
|
{
|
|
if (renderer.sharedMaterials[i] != renderer.sharedMaterials[0])
|
|
allSame = false;
|
|
}
|
|
|
|
if (allSame)
|
|
{
|
|
// Set master MaterialPropertyBlock
|
|
mpb.Clear();
|
|
var o = materialOverrides.Find(x => x.material == renderer.sharedMaterials[0]);
|
|
if (o == null || o.active == false)
|
|
{
|
|
renderer.SetPropertyBlock(null);
|
|
}
|
|
else
|
|
{
|
|
if (o.propertyOverrideAsset != null)
|
|
ApplyOverrides(mpb, o.propertyOverrideAsset.propertyOverrides);
|
|
ApplyOverrides(mpb, o.propertyOverrides);
|
|
renderer.SetPropertyBlock(mpb);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Set specific MaterialPropertyBlocks
|
|
for (int i = 0, c = renderer.sharedMaterials.Length; i < c; i++)
|
|
{
|
|
var o = materialOverrides.Find(x => x.material == renderer.sharedMaterials[i]);
|
|
if (o == null || o.active == false)
|
|
{
|
|
renderer.SetPropertyBlock(null, i);
|
|
}
|
|
else
|
|
{
|
|
mpb.Clear();
|
|
if (o.propertyOverrideAsset != null)
|
|
ApplyOverrides(mpb, o.propertyOverrideAsset.propertyOverrides);
|
|
ApplyOverrides(mpb, o.propertyOverrides);
|
|
renderer.SetPropertyBlock(mpb, i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Applies a list of individual override values to an mpb
|
|
void ApplyOverrides(MaterialPropertyBlock mpb, List<ShaderPropertyValue> overrides)
|
|
{
|
|
foreach (var spv in overrides)
|
|
{
|
|
switch (spv.type)
|
|
{
|
|
case ShaderPropertyType.Color:
|
|
mpb.SetColor(spv.propertyName, spv.colValue);
|
|
break;
|
|
case ShaderPropertyType.Float:
|
|
case ShaderPropertyType.Range:
|
|
mpb.SetFloat(spv.propertyName, spv.floatValue);
|
|
break;
|
|
case ShaderPropertyType.Vector:
|
|
mpb.SetVector(spv.propertyName, spv.vecValue);
|
|
break;
|
|
case ShaderPropertyType.TexEnv:
|
|
if (spv.texValue != null)
|
|
mpb.SetTexture(spv.propertyName, spv.texValue);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|