Files
zeling_v2/Assets/LWGUI-1.14.1/Editor/ShaderPropertyPreset.cs

257 lines
6.5 KiB
C#

// Copyright (c) 2022 Jason Ma
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace LWGUI
{
[CreateAssetMenu(fileName = "LWGUI_ShaderPropertyPreset.asset", menuName = "LWGUI/Shader Property Preset")]
public class ShaderPropertyPreset : ScriptableObject
{
public enum PropertyType
{
Color,
Vector,
Float,
Range,
Texture,
}
[Serializable]
public class PropertyValue
{
public PropertyValue(MaterialProperty prop)
{
CopyFromMaterialProperty(prop);
}
public string propertyName;
public PropertyType propertyType;
public float floatValue;
public Color colorValue;
public Vector4 vectorValue;
public Texture textureValue;
private int propertyNameID = -1;
public void Apply(Material material, bool isDefaultMaterial, PerFrameData perFrameData = null)
{
if (propertyNameID == -1 || !material.HasProperty(propertyNameID))
propertyNameID = Shader.PropertyToID(propertyName);
if (!material.HasProperty(propertyNameID))
{
var propertyNameLower = propertyName.ToLower();
switch (propertyNameLower)
{
case "renderqueue":
material.renderQueue = (int)floatValue;
return;
default:
// Debug.LogWarning("Unable to find Preset Property: " + propertyName + " in Material: " + material + "!");
return;
}
}
var isPropertyOtherMaterials = !isDefaultMaterial && perFrameData == null;
if (isPropertyOtherMaterials || isDefaultMaterial)
{
switch (propertyType)
{
case PropertyType.Color:
material.SetColor(propertyNameID, colorValue);
break;
case PropertyType.Vector:
material.SetVector(propertyNameID, vectorValue);
break;
case PropertyType.Float:
case PropertyType.Range:
material.SetFloat(propertyNameID, floatValue);
break;
case PropertyType.Texture:
material.SetTexture(propertyNameID, textureValue);
break;
}
if (isPropertyOtherMaterials)
MaterialEditor.ApplyMaterialPropertyDrawers(material);
}
else
// is Property Primary Material
{
var propDynamicData = perFrameData.propertyDatas[propertyName];
var prop = propDynamicData.property;
switch (propertyType)
{
case PropertyType.Color:
prop.colorValue = colorValue;
break;
case PropertyType.Vector:
prop.vectorValue = vectorValue;
break;
case PropertyType.Float:
case PropertyType.Range:
prop.floatValue = floatValue;
break;
case PropertyType.Texture:
prop.textureValue = textureValue;
break;
}
propDynamicData.hasRevertChanged = true;
}
}
public void CopyFromMaterialProperty(MaterialProperty prop)
{
propertyName = prop.name;
switch (prop.type)
{
case MaterialProperty.PropType.Color:
propertyType = PropertyType.Color;
colorValue = prop.colorValue;
break;
case MaterialProperty.PropType.Vector:
propertyType = PropertyType.Vector;
vectorValue = prop.vectorValue;
break;
#if UNITY_2021_1_OR_NEWER
case MaterialProperty.PropType.Int:
#endif
case MaterialProperty.PropType.Float:
propertyType = PropertyType.Float;
floatValue = prop.floatValue;
break;
case MaterialProperty.PropType.Range:
propertyType = PropertyType.Range;
floatValue = prop.floatValue;
break;
case MaterialProperty.PropType.Texture:
propertyType = PropertyType.Texture;
textureValue = prop.textureValue;
break;
}
}
public void OnValidate()
{
propertyNameID = -1;
}
}
[Serializable]
public class Preset
{
public string presetName;
public List<PropertyValue> propertyValues = new List<PropertyValue>();
public void ApplyToDefaultMaterial(Material material)
{
foreach (var propertyValue in propertyValues)
propertyValue.Apply(material, true);
}
public PropertyValue GetPropertyValue(string propName)
{
PropertyValue result = null;
if (propertyValues != null)
{
foreach (var propertyValue in propertyValues)
{
if (propertyValue.propertyName == propName)
{
result = propertyValue;
break;
}
}
}
return result;
}
public void AddOrUpdate(MaterialProperty prop)
{
var propertyValue = GetPropertyValue(prop.name);
if (propertyValue != null)
propertyValue.CopyFromMaterialProperty(prop);
else
propertyValues.Add(new PropertyValue(prop));
}
public void AddOrUpdateIncludeExtraProperties(LWGUI lwgui, MaterialProperty prop)
{
AddOrUpdate(prop);
foreach (var extraPropName in lwgui.perShaderData.propertyDatas[prop.name].extraPropNames)
{
AddOrUpdate(lwgui.perFrameData.propertyDatas[extraPropName].property);
}
}
public void Remove(string propName)
{
var propertyValue = GetPropertyValue(propName);
if (propertyValue != null)
propertyValues.Remove(propertyValue);
}
public void RemoveIncludeExtraProperties(LWGUI lwgui, string propName)
{
Remove(propName);
foreach (var extraPropName in lwgui.perShaderData.propertyDatas[propName].extraPropNames)
{
Remove(lwgui.perFrameData.propertyDatas[extraPropName].property.name);
}
}
}
public List<Preset> presets;
// private void Awake()
// {
// Debug.Log($"{this.name} Awake");
// }
//
// private void OnDestroy()
// {
// Debug.Log($"{this.name} OnDestroy");
// }
//
// private void OnDisable()
// {
// Debug.Log($"{this.name} OnDisable");
// }
//
// private void Reset()
// {
// Debug.Log($"{this.name} Reset");
// }
private void OnValidate()
{
// Debug.Log($"{this.name} OnValidate");
PresetHelper.ForceInit();
}
private void OnEnable()
{
// Debug.Log($"{this.name} OnEnable");
// manually added when a preset is manually created
if (PresetHelper.IsInitComplete)
PresetHelper.AddPreset(this);
}
public void ApplyToMaterials(UnityEngine.Object[] materials, int presetIndex, PerFrameData perFrameData)
{
if (this.presets.Count == 0) return;
int index = (int)Mathf.Min(this.presets.Count - 1, Mathf.Max(0, presetIndex));
foreach (var propertyValue in this.presets[index].propertyValues)
{
for (int i = 0; i < materials.Length; i++)
{
var material = materials[i] as Material;
propertyValue.Apply(material, false, i == 0 ? perFrameData : null);
}
}
}
}
}