2025-07-21 05:42:20 -04:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
using System.Linq;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
using UnityEditor.AnimatedValues;
|
|
|
|
|
|
// using UnityEditor.Rendering.Universal.ShaderGUI;
|
|
|
|
|
|
using UnityEngine;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
using Random = UnityEngine.Random;
|
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
using UnityEngine.UIElements;
|
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
|
namespace NBShaderEditor
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
/*
|
|
|
|
|
|
多选材质面板的原则记录:
|
|
|
|
|
|
0、多选后 同时只会有1个matEditor。每个属性只会有一个MaterialProperty。但会有多个Mat以及Mat属性值。会有多个ShaderFlag以及ShaderFlag值。
|
|
|
|
|
|
1、当多选后,属性处于Mixed状态时。对propety.Value进行设置是不合法的。只有非Mixed状态才会完全设置。包括这样对property.Value值进行判断也是非法的。如果在不确定Mixed的情况下,应该通过遍历Mats[i].Get或Set进行操作。Flag亦同理。
|
|
|
|
|
|
2、drawBlock应该都传Property,让DrawBlock内能知道Mixed状态。然后在Block内需要判断状态是否明确才进行相关的操作。
|
|
|
|
|
|
3、drawBlock一般放需要绘制的行为。对数值修改的行为统一放到OnValueChangeCheckBlock。
|
|
|
|
|
|
4、所有在GUI上存储,并需要后续判断的状态,需要可以标记mixed状态。如果是枚举,需要有一个指定为-1的UnKnownOrMixed枚举。如果是bool,应该改为int值,并规定-1为UnKnownOrMixed状态。
|
|
|
|
|
|
5、对于属性值的更改设定,都应该在OnValueChange的情况下进行。
|
|
|
|
|
|
6、对于Toggle作用的方法,均应该有EditorOnly的Property进行标记Toggle储存。Keywords或者Flag应该是设定结果,而非Toggle标记。
|
|
|
|
|
|
7、DrawVectorComponent这种多个GUI公用一个property属性的情况,需要有手动的提供各个Component是否是Mixed的方案。
|
|
|
|
|
|
*/
|
2025-07-21 05:42:20 -04:00
|
|
|
|
public class ShaderGUIHelper
|
|
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
public ShaderGUIHelper()
|
|
|
|
|
|
{
|
|
|
|
|
|
Undo.undoRedoPerformed += OnUndoRedoPerformed;
|
|
|
|
|
|
}
|
|
|
|
|
|
private void OnUndoRedoPerformed()//定义一个Undo回调
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!shader) return;//会有一些空的Helper对象
|
|
|
|
|
|
DrawGradientUndoPerformed();
|
|
|
|
|
|
ResetTool?.NeedUpdate();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
public class ShaderPropertyPack
|
|
|
|
|
|
{
|
|
|
|
|
|
public MaterialProperty property;
|
|
|
|
|
|
public string name;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
public int index;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
public List<Material> mats;
|
|
|
|
|
|
public MaterialEditor matEditor;
|
|
|
|
|
|
public Shader shader;
|
|
|
|
|
|
// public List<ShaderPropertyPack> ShaderPropertyPacks = new List<ShaderPropertyPack>();
|
|
|
|
|
|
public Dictionary<string, ShaderPropertyPack> ShaderPropertyPacksDic =
|
|
|
|
|
|
new Dictionary<string, ShaderPropertyPack>();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
public ShaderFlagsBase[] shaderFlags = null;
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
public bool isClearUnUsedTexture = false;
|
|
|
|
|
|
|
|
|
|
|
|
Color defaultBackgroundColor;
|
|
|
|
|
|
Color animatedBackgroundColor=>Color.red;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
|
|
|
|
|
public void Init(MaterialEditor materialEditor, MaterialProperty[] properties,
|
|
|
|
|
|
ShaderFlagsBase[] shaderFlags_in = null, List<Material> mats_in = null)
|
|
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
defaultBackgroundColor = GUI.backgroundColor;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
shaderFlags = shaderFlags_in;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
// ShaderPropertyPacks.Clear();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
matEditor = materialEditor;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
mats = mats_in;
|
|
|
|
|
|
if (mats[0].shader != shader)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
shader = mats[0].shader;
|
|
|
|
|
|
ShaderPropertyPacksDic.Clear();
|
|
|
|
|
|
for (int i = 0; i < ShaderUtil.GetPropertyCount(shader); i++)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
ShaderPropertyPack pack = new ShaderPropertyPack();
|
|
|
|
|
|
pack.name = ShaderUtil.GetPropertyName(shader, i);
|
|
|
|
|
|
for (int index = 0; index < properties.Length; ++index)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
if (properties[index] != null && properties[index].name == pack.name)
|
|
|
|
|
|
{
|
|
|
|
|
|
pack.property = properties[index];
|
|
|
|
|
|
pack.index = index;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (index == properties.Length - 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError(pack.name + "找不到Properties");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ShaderPropertyPacks.Add(pack);
|
|
|
|
|
|
ShaderPropertyPacksDic.Add(pack.name,pack);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < ShaderUtil.GetPropertyCount(shader); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
string propertyName = ShaderUtil.GetPropertyName(shader, i);
|
|
|
|
|
|
ShaderPropertyPacksDic[propertyName].property = properties[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ResetTool == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
ResetTool = new ShaderGUIResetTool(this);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
ResetTool.EndInit();
|
|
|
|
|
|
ResetTool.Update();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
isClearUnUsedTexture = false;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private ShaderGUIToolBar _toolBar;
|
|
|
|
|
|
|
|
|
|
|
|
public ShaderGUIResetTool ResetTool;
|
|
|
|
|
|
public List<Renderer> renderersUsingThisMaterial = new List<Renderer>();
|
|
|
|
|
|
|
|
|
|
|
|
public bool IsPropertyAnimated(string propertyName,params string[] componentNames)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (AnimationMode.InAnimationMode())
|
|
|
|
|
|
{
|
|
|
|
|
|
string propertyPath = "material." + propertyName;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var r in renderersUsingThisMaterial)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (componentNames.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var component in componentNames)
|
|
|
|
|
|
{
|
|
|
|
|
|
string propertyPathWithComponent = propertyPath +"." +component;
|
|
|
|
|
|
if (AnimationMode.IsPropertyAnimated(r, propertyPathWithComponent))
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
if (AnimationMode.IsPropertyAnimated(r, propertyPath))
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
// Debug.Log(propertyName);
|
|
|
|
|
|
return true;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
public void DrawToolBar()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_toolBar == null) _toolBar = new ShaderGUIToolBar(this);
|
|
|
|
|
|
_toolBar.DrawToolbar();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void DrawToggleFoldOut(int foldOutFlagBit,int foldOutFlagIndex, int animBoolIndex,string label, string propertyName,
|
|
|
|
|
|
int flagBitsName = 0,
|
|
|
|
|
|
int flagIndex = 0, string shaderKeyword = null, string shaderPassName = null, bool isIndentBlock = true, FontStyle fontStyle = FontStyle.Normal,
|
|
|
|
|
|
Action<MaterialProperty> drawBlock = null,Action<MaterialProperty> drawEndChangeCheck = null,bool isSharedGlobalParent = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool foldOutState = shaderFlags[0].CheckFlagBits(foldOutFlagBit, index: foldOutFlagIndex);
|
|
|
|
|
|
AnimBool animBool = GetAnimBool(foldOutFlagBit, animBoolIndex, foldOutFlagIndex); //foldOut里的第一组。
|
|
|
|
|
|
animBool.target = foldOutState;
|
|
|
|
|
|
DrawToggleFoldOut(ref animBool, label, propertyName, flagBitsName, flagIndex, shaderKeyword,
|
|
|
|
|
|
shaderPassName, isIndentBlock, fontStyle, drawBlock, drawEndChangeCheck,isSharedGlobalParent:isSharedGlobalParent);
|
|
|
|
|
|
foldOutState = animBool.target;
|
|
|
|
|
|
if (foldOutState)
|
|
|
|
|
|
{
|
|
|
|
|
|
shaderFlags[0].SetFlagBits(foldOutFlagBit, index: foldOutFlagIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
shaderFlags[0].ClearFlagBits(foldOutFlagBit, index: foldOutFlagIndex);
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
public void ColorProperty(string label, string propertyName,bool showAlpha = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
|
|
|
|
ShaderPropertyPack shaderPropertyPack = ShaderPropertyPacksDic[propertyName];
|
|
|
|
|
|
MaterialProperty prop = shaderPropertyPack.property;
|
|
|
|
|
|
Color color = shaderPropertyPack.property.colorValue;
|
|
|
|
|
|
Rect position = EditorGUILayout.GetControlRect();
|
|
|
|
|
|
// MaterialEditor.BeginProperty(position, prop);
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.BeginChangeCheck();
|
2026-03-14 03:13:10 -04:00
|
|
|
|
bool hdr = (prop.propertyFlags & UnityEngine.Rendering.ShaderPropertyFlags.HDR) != 0;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
if (IsPropertyAnimated(propertyName,"r","g","b","a"))
|
|
|
|
|
|
{
|
|
|
|
|
|
GUI.backgroundColor = animatedBackgroundColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
color = EditorGUI.ColorField(position, new GUIContent(label), prop.colorValue, true, showAlpha, hdr);
|
|
|
|
|
|
GUI.backgroundColor = defaultBackgroundColor;
|
|
|
|
|
|
Action onEndChaneChange = () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
prop.colorValue = color;
|
|
|
|
|
|
ResetTool.CheckOnValueChange((label,propertyName));
|
|
|
|
|
|
};
|
|
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
|
|
|
|
{
|
|
|
|
|
|
onEndChaneChange();
|
|
|
|
|
|
}
|
|
|
|
|
|
ResetTool.DrawResetModifyButton(new Rect(),(label,shaderPropertyPack.name),shaderPropertyPack,resetAction: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
color = prop.colorValue;
|
|
|
|
|
|
},onValueChangedCallBack: onEndChaneChange);
|
|
|
|
|
|
// MaterialEditor.EndProperty();
|
|
|
|
|
|
// matEditor.ColorProperty(GetProperty(propertyName), label);
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
|
|
ResetTool.EndResetModifyButtonScope();
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
public void DrawBigBlockFoldOut(int foldOutFlagBit,int foldOutFlagIndex,int animBoolIndex ,string label, Action drawBlock,bool isResetButtonBias = true)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.Space();
|
2025-08-27 21:45:18 -04:00
|
|
|
|
DrawFoldOut(foldOutFlagBit,foldOutFlagIndex,animBoolIndex, label,FontStyle.Bold, drawBlock,isResetButtonBias);
|
2025-07-21 05:42:20 -04:00
|
|
|
|
GuiLine();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
private AnimBool[] animBoolArr = new AnimBool[96];//先假定有3组。和存好的bit一一对应。
|
|
|
|
|
|
|
|
|
|
|
|
public AnimBool GetAnimBool(int flagBit, int AnimBoolIndex,int flagIndex)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
int bitPos = 0;
|
|
|
|
|
|
for (int i = 0; i < 32; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if ((flagBit & (1 << i)) > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
bitPos = i;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
int arrIndex = AnimBoolIndex * 32 + bitPos;
|
|
|
|
|
|
// Debug.Log(arrIndex.ToString() +"---"+ animBoolArr[arrIndex]);
|
|
|
|
|
|
if (animBoolArr[arrIndex] == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
animBoolArr[arrIndex] = new AnimBool(shaderFlags[0].CheckFlagBits(flagBit,index:flagIndex));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return animBoolArr[arrIndex];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void DrawFoldOut(int foldOutFlagBit,int foldOutFlagIndex,int animBoolIndex, String label,FontStyle fontStyle = FontStyle.Normal, Action drawBlock = null,bool isResetButtonBias = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool foldOutState = shaderFlags[0].CheckFlagBits(foldOutFlagBit, index: foldOutFlagIndex);
|
|
|
|
|
|
AnimBool animBool = GetAnimBool(foldOutFlagBit, animBoolIndex, foldOutFlagIndex);
|
|
|
|
|
|
animBool.target = foldOutState;
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
|
|
|
|
var rect = EditorGUILayout.GetControlRect();
|
|
|
|
|
|
var foldoutRect = new Rect(rect.x, rect.y, rect.width, rect.height);
|
2025-08-27 21:45:18 -04:00
|
|
|
|
foldoutRect.width -= 2 * ResetTool.ResetButtonSize;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
var labelRect = new Rect(rect.x + 2f, rect.y, rect.width - 2f, rect.height);
|
2025-08-27 21:45:18 -04:00
|
|
|
|
var resetRect = rect;
|
|
|
|
|
|
resetRect.x = rect.x + rect.width - ResetTool.ResetButtonSize ;
|
|
|
|
|
|
if (isResetButtonBias) resetRect.x -= 3f;
|
|
|
|
|
|
resetRect.width = ResetTool.ResetButtonSize;
|
|
|
|
|
|
|
|
|
|
|
|
animBool.target = EditorGUI.Foldout(foldoutRect, animBool.target, string.Empty, true);
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
FontStyle origFontStyle = EditorStyles.label.fontStyle;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
EditorStyles.label.fontStyle = fontStyle;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
EditorGUI.LabelField(labelRect, label);
|
|
|
|
|
|
EditorStyles.label.fontStyle = origFontStyle;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
|
|
|
|
|
|
ResetTool.DrawResetModifyButton(resetRect,label);
|
2025-07-21 05:42:20 -04:00
|
|
|
|
EditorGUILayout.EndHorizontal();
|
2025-08-27 21:45:18 -04:00
|
|
|
|
|
|
|
|
|
|
float faded = animBool.faded;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
if (faded == 0) faded = 0.00001f;
|
|
|
|
|
|
EditorGUILayout.BeginFadeGroup(faded);
|
|
|
|
|
|
EditorGUI.indentLevel++;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
drawBlock?.Invoke();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
EditorGUI.indentLevel--;
|
|
|
|
|
|
EditorGUILayout.EndFadeGroup();
|
2025-08-27 21:45:18 -04:00
|
|
|
|
foldOutState = animBool.target;
|
|
|
|
|
|
if (foldOutState)
|
|
|
|
|
|
{
|
|
|
|
|
|
shaderFlags[0].SetFlagBits(foldOutFlagBit, index: foldOutFlagIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
shaderFlags[0].ClearFlagBits(foldOutFlagBit, index: foldOutFlagIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
ResetTool.EndResetModifyButtonScope();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void DrawBigBlockWithToggle(String label, string propertyName, int flagBitsName = 0, int flagIndex = 0,
|
|
|
|
|
|
string shaderKeyword = null, string shaderPassName = null, string shaderPassName2 = null,
|
2025-08-27 21:45:18 -04:00
|
|
|
|
Action<MaterialProperty> drawBlock = null)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
DrawToggle(label, propertyName, flagBitsName, flagIndex, shaderKeyword, shaderPassName, shaderPassName2,
|
|
|
|
|
|
isIndentBlock: true, FontStyle.Bold, drawBlock: drawBlock);
|
|
|
|
|
|
GuiLine();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
public void DrawToggleFoldOut(ref AnimBool foldOutAnimBool, String label, string propertyName,
|
2025-07-21 05:42:20 -04:00
|
|
|
|
int flagBitsName = 0,
|
|
|
|
|
|
int flagIndex = 0, string shaderKeyword = null, string shaderPassName = null, bool isIndentBlock = true,
|
|
|
|
|
|
FontStyle fontStyle = FontStyle.Normal,
|
2025-08-27 21:45:18 -04:00
|
|
|
|
Action<MaterialProperty> drawBlock = null, Action<MaterialProperty> drawEndChangeCheck = null,bool isSharedGlobalParent = false)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
ShaderPropertyPack propertyPack = ShaderPropertyPacksDic[propertyName];
|
|
|
|
|
|
MaterialProperty toggleProp = GetProperty(propertyName);
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
if (fontStyle == FontStyle.Bold)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
|
|
|
|
var rect = EditorGUILayout.GetControlRect();
|
2025-08-27 21:45:18 -04:00
|
|
|
|
var toggleRect = rect;
|
|
|
|
|
|
toggleRect.x += EditorGUIUtility.labelWidth;
|
|
|
|
|
|
toggleRect.width -= EditorGUIUtility.labelWidth;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
|
|
|
|
|
var foldoutRect = new Rect(rect.x, rect.y, rect.width, rect.height);
|
|
|
|
|
|
foldoutRect.width = toggleRect.x - foldoutRect.x;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
var labelRect = new Rect(rect.x , rect.y, rect.width , rect.height);
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
// bool isToggle = false;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
// 必须先画Toggle,不然按钮会被FoldOut和Label覆盖。
|
2025-08-27 21:45:18 -04:00
|
|
|
|
DrawToggle(string.Empty, propertyName, flagBitsName, flagIndex, shaderKeyword, shaderPassName, isIndentBlock: false, fontStyle: FontStyle.Normal, rect: toggleRect, drawEndChangeCheck: drawEndChangeCheck,isSharedGlobalParent:isSharedGlobalParent);
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
foldOutAnimBool.target = EditorGUI.Foldout(foldoutRect, foldOutAnimBool.target, string.Empty, true);
|
|
|
|
|
|
var origFontStyle = EditorStyles.label.fontStyle;
|
|
|
|
|
|
EditorStyles.label.fontStyle = fontStyle;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
EditorGUI.LabelField(labelRect, label);
|
|
|
|
|
|
EditorStyles.label.fontStyle = origFontStyle;
|
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
|
|
if (isIndentBlock) EditorGUI.indentLevel++;
|
|
|
|
|
|
float faded = foldOutAnimBool.faded;
|
|
|
|
|
|
if (faded == 0) faded = 0.00001f; //用于欺骗FadeGroup,不要让他真的关闭了。这样会藏不住相关的GUI。我们的目的是,GUI藏住,但是逻辑还是在跑。drawBlock要执行。
|
|
|
|
|
|
EditorGUILayout.BeginFadeGroup(faded);
|
|
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
bool isDisabledGroup = toggleProp.hasMixedValue || toggleProp.floatValue < 0.5f;
|
|
|
|
|
|
EditorGUI.BeginDisabledGroup(isDisabledGroup);
|
|
|
|
|
|
drawBlock?.Invoke(toggleProp);
|
2025-07-21 05:42:20 -04:00
|
|
|
|
EditorGUI.EndDisabledGroup();
|
|
|
|
|
|
}
|
|
|
|
|
|
EditorGUILayout.EndFadeGroup();
|
|
|
|
|
|
if (isIndentBlock) EditorGUI.indentLevel--;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
|
|
|
|
|
|
ResetTool.EndResetModifyButtonScope();//开始是在DrawToggle里开始的
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
public void DrawToggle(String label, string propertyName, int flagBitsName = 0, int flagIndex = 0,
|
2025-07-21 05:42:20 -04:00
|
|
|
|
string shaderKeyword = null, string shaderPassName = null, string shaderPassName2 = null,
|
|
|
|
|
|
bool isIndentBlock = true, FontStyle fontStyle = FontStyle.Normal, Rect rect = new Rect(),
|
2025-08-27 21:45:18 -04:00
|
|
|
|
Action<MaterialProperty> drawBlock = null, Action<MaterialProperty> drawEndChangeCheck = null,bool isSharedGlobalParent = false)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
if (GetProperty(propertyName) == null)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
return;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
if (fontStyle == FontStyle.Bold)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
|
|
|
|
|
|
MaterialProperty toggleProperty = GetProperty(propertyName);
|
|
|
|
|
|
ShaderPropertyPack propertyPack = ShaderPropertyPacksDic[propertyName];
|
|
|
|
|
|
EditorGUI.showMixedValue = toggleProperty.hasMixedValue;
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
EditorGUI.BeginChangeCheck();
|
2025-08-27 21:45:18 -04:00
|
|
|
|
bool isToggle = toggleProperty.floatValue > 0.5f ? true : false;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
var origFontStyle = EditorStyles.label.fontStyle;
|
|
|
|
|
|
EditorStyles.label.fontStyle = fontStyle;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
Rect resetButtonRect = rect;
|
|
|
|
|
|
if (label.Length == 0) //给FoldOut功能使用。
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
rect.x += 2f;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
isToggle = EditorGUI.Toggle(rect, isToggle, EditorStyles.toggle);
|
2025-08-27 21:45:18 -04:00
|
|
|
|
resetButtonRect.x = resetButtonRect.x + resetButtonRect.width - ResetTool.ResetButtonSize;
|
|
|
|
|
|
resetButtonRect.width = ResetTool.ResetButtonSize;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
isToggle = EditorGUILayout.Toggle(label, isToggle);
|
|
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
EditorStyles.label.fontStyle = origFontStyle;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
Action onEndChangeCheck = () =>
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
toggleProperty.floatValue = isToggle ? 1.0f : 0.0f;
|
|
|
|
|
|
ResetTool.CheckOnValueChange((label,propertyName));
|
|
|
|
|
|
if (!toggleProperty.hasMixedValue)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
for (int i = 0; i < mats.Count; i++)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
if (isToggle)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
mats[i].SetFloat(propertyName,1);
|
|
|
|
|
|
|
|
|
|
|
|
if (flagBitsName != 0 && shaderFlags[i] != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
shaderFlags[i].SetFlagBits(flagBitsName, index: flagIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (shaderKeyword != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
mats[i].EnableKeyword(shaderKeyword);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (shaderPassName != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
mats[i].SetShaderPassEnabled(shaderPassName, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (shaderPassName2 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
mats[i].SetShaderPassEnabled(shaderPassName2, true);
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
else
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
|
|
|
|
|
|
mats[i].SetFloat(propertyName,0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (flagBitsName != 0 && shaderFlags[i] != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
shaderFlags[i].ClearFlagBits(flagBitsName, index: flagIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (shaderKeyword != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
mats[i].DisableKeyword(shaderKeyword);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (shaderPassName != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
mats[i].SetShaderPassEnabled(shaderPassName, false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (shaderPassName2 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
mats[i].SetShaderPassEnabled(shaderPassName2, false);
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
drawEndChangeCheck?.Invoke(toggleProperty);
|
|
|
|
|
|
};
|
|
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
|
|
|
|
{
|
|
|
|
|
|
onEndChangeCheck();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ResetTool.DrawResetModifyButton(resetButtonRect,(label,propertyPack.name),propertyPack,resetAction: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
isToggle = propertyPack.property.floatValue > 0.5f ? true : false;
|
|
|
|
|
|
},onValueChangedCallBack:onEndChangeCheck,isSharedGlobalParent:isSharedGlobalParent);
|
|
|
|
|
|
|
|
|
|
|
|
if (label.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (isIndentBlock) EditorGUI.indentLevel++;
|
|
|
|
|
|
drawBlock?.Invoke(toggleProperty);
|
|
|
|
|
|
if (isIndentBlock) EditorGUI.indentLevel--;
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.showMixedValue = false;
|
|
|
|
|
|
if (rect.width <= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
ResetTool.EndResetModifyButtonScope();//如果是DrawFoldOut,需要在DrawFoldOut里去结束。
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
void RangeVecHasMixedValue(string rangePropertyName, out bool minValueHasMixed, out bool maxValueHasMixed)
|
|
|
|
|
|
{
|
|
|
|
|
|
minValueHasMixed = false;
|
|
|
|
|
|
maxValueHasMixed = false;
|
|
|
|
|
|
if (mats.Count > 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
MaterialProperty rangeProperty = GetProperty(rangePropertyName);
|
|
|
|
|
|
float minValue = 0;
|
|
|
|
|
|
float maxValue = 0;
|
|
|
|
|
|
for (int i = 0; i < mats.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector4 rangeVec = mats[i].GetVector(rangePropertyName);
|
|
|
|
|
|
if (i == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
minValue = rangeVec.x;
|
|
|
|
|
|
maxValue = rangeVec.y;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
if (!Mathf.Approximately(minValue, rangeVec.x))
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
minValueHasMixed = true;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
if (!Mathf.Approximately(maxValue, rangeVec.y))
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
maxValueHasMixed = true;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
bool RangePropIsDefaultValue(string rangePropertyName)
|
|
|
|
|
|
{
|
|
|
|
|
|
MaterialProperty rangeProperty = GetProperty(rangePropertyName);
|
|
|
|
|
|
return mats[0].GetVector(rangePropertyName) == shader.GetPropertyDefaultVectorValue(ShaderPropertyPacksDic[rangePropertyName].index) && !rangeProperty.hasMixedValue;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
void DrawSlider(string label, ref float value,ref float min,ref float max,bool isValueMixed,string rangePropertyName = null,bool propIsAnimated = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (rangePropertyName == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUI.showMixedValue = isValueMixed;
|
|
|
|
|
|
if (propIsAnimated) GUI.backgroundColor = animatedBackgroundColor;
|
|
|
|
|
|
value = EditorGUILayout.Slider(label,value,min,max);
|
|
|
|
|
|
GUI.backgroundColor = defaultBackgroundColor;
|
|
|
|
|
|
EditorGUI.showMixedValue = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Rect rect = EditorGUILayout.GetControlRect();
|
|
|
|
|
|
Rect labelRect = rect;
|
|
|
|
|
|
labelRect.width = EditorGUIUtility.labelWidth;
|
|
|
|
|
|
Rect valueRect = rect;
|
|
|
|
|
|
valueRect.x += EditorGUIUtility.labelWidth;
|
|
|
|
|
|
valueRect.width -= EditorGUIUtility.labelWidth;
|
|
|
|
|
|
// EditorGUI.DrawRect(valueRect,Color.red);
|
|
|
|
|
|
float rangeWidth = 50f;
|
|
|
|
|
|
Rect minRect = valueRect;
|
|
|
|
|
|
minRect.width = rangeWidth;
|
|
|
|
|
|
minRect.x -= indent;
|
|
|
|
|
|
minRect.width += indent;
|
|
|
|
|
|
// EditorGUI.DrawRect(minRect,Color.green);
|
|
|
|
|
|
Rect maxRect = valueRect;
|
|
|
|
|
|
maxRect.x += valueRect.width;
|
|
|
|
|
|
maxRect.x -= rangeWidth;
|
|
|
|
|
|
maxRect.width = rangeWidth;
|
|
|
|
|
|
maxRect.x -= indent;
|
|
|
|
|
|
maxRect.width += indent;
|
|
|
|
|
|
valueRect.x += rangeWidth;
|
|
|
|
|
|
valueRect.width -= 2*rangeWidth;
|
|
|
|
|
|
valueRect.x -= indent;
|
|
|
|
|
|
valueRect.width += indent;
|
|
|
|
|
|
valueRect.x += 4f;
|
|
|
|
|
|
valueRect.width -= 8f;
|
|
|
|
|
|
EditorGUI.LabelField(labelRect, label);
|
|
|
|
|
|
|
|
|
|
|
|
RangeVecHasMixedValue(rangePropertyName,out bool minValueHasMixed,out bool maxValueHasMixed);
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.showMixedValue = minValueHasMixed;
|
|
|
|
|
|
min = EditorGUI.FloatField(minRect, GUIContent.none, min);
|
|
|
|
|
|
EditorGUI.showMixedValue = maxValueHasMixed;
|
|
|
|
|
|
max = EditorGUI.FloatField(maxRect, GUIContent.none, max);
|
|
|
|
|
|
EditorGUI.showMixedValue = isValueMixed;
|
|
|
|
|
|
if (propIsAnimated)
|
|
|
|
|
|
{
|
|
|
|
|
|
GUI.backgroundColor = animatedBackgroundColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
value = EditorGUI.Slider(valueRect, value, min, max);
|
|
|
|
|
|
GUI.backgroundColor = defaultBackgroundColor;
|
|
|
|
|
|
EditorGUI.showMixedValue = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
public void DrawSlider(string label, string propertyName,float min = 0,float max = 1,string rangePropertyName = null, Action<float> drawBlock = null)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
bool hasMixedValue = GetProperty(propertyName).hasMixedValue;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
float f = GetProperty(propertyName).floatValue;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
bool customedRange = rangePropertyName != null;
|
|
|
|
|
|
Vector4 rangeVec = Vector4.zero;
|
|
|
|
|
|
if (customedRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
rangeVec = GetProperty(rangePropertyName).vectorValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
EditorGUI.BeginChangeCheck();
|
2025-08-27 21:45:18 -04:00
|
|
|
|
if (IsPropertyAnimated(propertyName))
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
GUI.backgroundColor = animatedBackgroundColor;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
bool isPropAnimated = IsPropertyAnimated(propertyName);
|
|
|
|
|
|
if (customedRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
DrawSlider(label, ref f, ref rangeVec.x,ref rangeVec.y,hasMixedValue,rangePropertyName,isPropAnimated);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
DrawSlider(label, ref f, ref min,ref max,hasMixedValue,propIsAnimated:isPropAnimated);
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
GUI.backgroundColor = defaultBackgroundColor;
|
|
|
|
|
|
Action endChangCallBack= () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
GetProperty(propertyName).floatValue = f;
|
|
|
|
|
|
if (customedRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
GetProperty(rangePropertyName).vectorValue = rangeVec;
|
|
|
|
|
|
}
|
|
|
|
|
|
ResetTool.CheckOnValueChange((label,propertyName));
|
|
|
|
|
|
};
|
2025-07-21 05:42:20 -04:00
|
|
|
|
EditorGUI.showMixedValue = false;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
|
|
|
|
{
|
|
|
|
|
|
endChangCallBack.Invoke();
|
|
|
|
|
|
}
|
|
|
|
|
|
ResetTool.DrawResetModifyButton(new Rect(),(label,propertyName),resetCallBack: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
f = shader.GetPropertyDefaultFloatValue(ShaderPropertyPacksDic[propertyName].index);
|
|
|
|
|
|
if (customedRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
rangeVec = shader.GetPropertyDefaultVectorValue(ShaderPropertyPacksDic[rangePropertyName].index);
|
|
|
|
|
|
}
|
|
|
|
|
|
},onValueChangedCallBack: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
endChangCallBack();
|
|
|
|
|
|
}
|
|
|
|
|
|
,checkHasModifyOnValueChange:
|
|
|
|
|
|
() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
bool isModify = !Mathf.Approximately(mats[0].GetFloat(propertyName),shader.GetPropertyDefaultFloatValue(ShaderPropertyPacksDic[propertyName].index));
|
|
|
|
|
|
if (customedRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
isModify |= !RangePropIsDefaultValue(rangePropertyName);
|
|
|
|
|
|
}
|
|
|
|
|
|
return isModify;
|
|
|
|
|
|
},checkHasMixedValueOnValueChange:
|
|
|
|
|
|
() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
bool hasMixedValue = false;
|
|
|
|
|
|
hasMixedValue |= GetProperty(propertyName).hasMixedValue;
|
|
|
|
|
|
if (customedRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
RangeVecHasMixedValue(rangePropertyName,out bool minValueHasMixed,out bool maxValueHasMixed);
|
|
|
|
|
|
hasMixedValue |= minValueHasMixed;
|
|
|
|
|
|
hasMixedValue |= maxValueHasMixed;
|
|
|
|
|
|
}
|
|
|
|
|
|
return hasMixedValue;
|
|
|
|
|
|
});
|
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
|
|
drawBlock?.Invoke(f);
|
|
|
|
|
|
ResetTool.EndResetModifyButtonScope();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void DrawFloat(string label, string propertyName, bool isReciprocal = false,
|
2025-08-27 21:45:18 -04:00
|
|
|
|
Action<MaterialProperty> drawBlock = null)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
|
|
|
|
|
EditorGUI.showMixedValue = GetProperty(propertyName).hasMixedValue;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
MaterialProperty floatProperty = GetProperty(propertyName);
|
|
|
|
|
|
float f = floatProperty.floatValue;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
if (isReciprocal) f = 1 / f;
|
|
|
|
|
|
EditorGUI.BeginChangeCheck();
|
2025-08-27 21:45:18 -04:00
|
|
|
|
Action endChangeCallback = () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
floatProperty.floatValue = f;
|
|
|
|
|
|
ResetTool.CheckOnValueChange((label,propertyName));
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
|
|
|
|
if (IsPropertyAnimated(propertyName))
|
|
|
|
|
|
{
|
|
|
|
|
|
GUI.backgroundColor = animatedBackgroundColor;
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
f = EditorGUILayout.FloatField(label, f);
|
2025-08-27 21:45:18 -04:00
|
|
|
|
GUI.backgroundColor = defaultBackgroundColor;
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
if (isReciprocal) f = 1 / f;
|
|
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
endChangeCallback.Invoke();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
|
|
|
|
|
|
ResetTool.DrawResetModifyButton(new Rect(),(label,propertyName),ShaderPropertyPacksDic[propertyName],resetAction: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
f = floatProperty.floatValue;
|
|
|
|
|
|
},onValueChangedCallBack:endChangeCallback);
|
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
drawBlock?.Invoke(floatProperty);
|
2025-07-21 05:42:20 -04:00
|
|
|
|
EditorGUI.showMixedValue = false;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
ResetTool.EndResetModifyButtonScope();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
Vector2 GetVec2InVec4(Vector4 vec4,bool isFirstLine)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
if (isFirstLine)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
return new Vector2(vec4.x, vec4.y);
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
else
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
return new Vector2(vec4.z, vec4.w);
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Vector4 SetVec2InVec4(Vector4 vec4,bool isFirstLine,Vector2 vec2Value)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isFirstLine)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
vec4.x = vec2Value.x;
|
|
|
|
|
|
vec4.y = vec2Value.y;
|
|
|
|
|
|
return vec4;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
vec4.z = vec2Value.x;
|
|
|
|
|
|
vec4.w = vec2Value.y;
|
|
|
|
|
|
return vec4;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
Vector2 GetVecInTwoLineDefaultValue(string propertyName, bool isFirstLine)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
ShaderPropertyPack propertyPack = ShaderPropertyPacksDic[propertyName];
|
|
|
|
|
|
Vector4 defaultVector = shader.GetPropertyDefaultVectorValue(propertyPack.index);
|
|
|
|
|
|
if (isFirstLine)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
return new Vector2(defaultVector.x, defaultVector.y);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return new Vector2(defaultVector.z, defaultVector.w);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Vector4In2LineHasMixedValue(string propertyName, bool isFirstLine)
|
|
|
|
|
|
{
|
|
|
|
|
|
MaterialProperty matProp = GetProperty(propertyName);
|
|
|
|
|
|
if (matProp.hasMixedValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector2 val = Vector2.zero;
|
|
|
|
|
|
for (int i = 0; i < mats.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector2 matValue = GetVec2InVec4(mats[i].GetVector(propertyName), isFirstLine);
|
|
|
|
|
|
if (i == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
val = matValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!val.Equals(matValue) )
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void DrawVector4In2Line(string propertyName, string label , bool isFirstLine,
|
|
|
|
|
|
Action drawBlock = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUI.showMixedValue = Vector4In2LineHasMixedValue(propertyName, isFirstLine);
|
|
|
|
|
|
MaterialProperty property = GetProperty(propertyName);
|
|
|
|
|
|
(string,string) nameTuple = (label,propertyName);
|
|
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
|
|
|
|
|
|
|
|
|
|
Vector2 vec2 = GetVec2InVec4(property.vectorValue, isFirstLine);
|
|
|
|
|
|
// vec2 = EditorGUILayout.Vector2Field(label, vec2);
|
|
|
|
|
|
Rect rect = EditorGUILayout.GetControlRect(true);
|
|
|
|
|
|
Rect labelRect = rect;
|
|
|
|
|
|
labelRect.width = EditorGUIUtility.labelWidth - indent;
|
|
|
|
|
|
EditorGUI.LabelField(labelRect, label);
|
|
|
|
|
|
Rect vec2Rect = rect;
|
|
|
|
|
|
vec2Rect.x += labelRect.width;
|
|
|
|
|
|
vec2Rect.width -= labelRect.width;
|
|
|
|
|
|
if (isFirstLine)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (IsPropertyAnimated(propertyName, "x", "y"))
|
|
|
|
|
|
{
|
|
|
|
|
|
GUI.backgroundColor = animatedBackgroundColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (IsPropertyAnimated(propertyName, "z", "w"))
|
|
|
|
|
|
{
|
|
|
|
|
|
GUI.backgroundColor = animatedBackgroundColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
vec2 = EditorGUI.Vector2Field(vec2Rect,"", vec2);
|
|
|
|
|
|
GUI.backgroundColor = defaultBackgroundColor;
|
|
|
|
|
|
|
|
|
|
|
|
Action vec2OnEndChangeCheck = () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
int shaderID = Shader.PropertyToID(propertyName);
|
|
|
|
|
|
for (int i = 0; i < mats.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector4 vec4 = mats[i].GetVector(shaderID);
|
|
|
|
|
|
vec4 = SetVec2InVec4(vec4, isFirstLine, vec2);
|
|
|
|
|
|
if (mats.Count == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
GetProperty(propertyName).vectorValue = vec4; //为了K动画,多选不能K动画。
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
mats[i].SetVector(shaderID, vec4);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
ResetTool.CheckOnValueChange(nameTuple);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
|
|
|
|
{
|
|
|
|
|
|
vec2OnEndChangeCheck();
|
|
|
|
|
|
}
|
|
|
|
|
|
EditorGUI.showMixedValue = false;
|
|
|
|
|
|
|
|
|
|
|
|
ResetTool.DrawResetModifyButton(new Rect(),nameTuple,
|
|
|
|
|
|
resetCallBack:()=>
|
|
|
|
|
|
{
|
|
|
|
|
|
vec2 = GetVecInTwoLineDefaultValue(propertyName, isFirstLine);
|
|
|
|
|
|
vec2OnEndChangeCheck();
|
|
|
|
|
|
},
|
|
|
|
|
|
onValueChangedCallBack:vec2OnEndChangeCheck,
|
|
|
|
|
|
checkHasModifyOnValueChange: () => GetVec2InVec4(mats[0].GetVector(propertyName), isFirstLine) != GetVecInTwoLineDefaultValue(propertyName, isFirstLine),
|
|
|
|
|
|
checkHasMixedValueOnValueChange:()=>Vector4In2LineHasMixedValue(propertyName, isFirstLine));
|
|
|
|
|
|
|
|
|
|
|
|
drawBlock?.Invoke();
|
|
|
|
|
|
ResetTool.EndResetModifyButtonScope();
|
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
float GetCompInVec4(Vector4 vec, string comp)
|
|
|
|
|
|
{
|
|
|
|
|
|
float f = 0;
|
|
|
|
|
|
switch (comp)
|
|
|
|
|
|
{
|
|
|
|
|
|
case "x":
|
2025-07-21 05:42:20 -04:00
|
|
|
|
f = vec.x;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "y":
|
|
|
|
|
|
f = vec.y;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "z":
|
|
|
|
|
|
f = vec.z;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "w":
|
|
|
|
|
|
f = vec.w;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return f;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
float GetCompDefaultValueInVec4(string propertyName, string comp)
|
|
|
|
|
|
{
|
|
|
|
|
|
ShaderPropertyPack propertyPack = ShaderPropertyPacksDic[propertyName];
|
|
|
|
|
|
Vector4 defaultValue = shader.GetPropertyDefaultVectorValue(propertyPack.index);
|
|
|
|
|
|
return GetCompInVec4(defaultValue, comp);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
Vector4 SetCompInVec4(Vector4 vec, string comp, float value)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (comp)
|
|
|
|
|
|
{
|
|
|
|
|
|
case "x":
|
|
|
|
|
|
vec.x = value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "y":
|
|
|
|
|
|
vec.y = value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "z":
|
|
|
|
|
|
vec.z = value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "w":
|
|
|
|
|
|
vec.w = value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return vec;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
bool Vector4ComponentHasMixedValue(string propertyName, string channel)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
MaterialProperty property = GetProperty(propertyName);
|
|
|
|
|
|
if (property.hasMixedValue)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
float val = 0;
|
|
|
|
|
|
for (int i = 0; i < mats.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (i == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
val = GetCompInVec4(mats[i].GetVector(propertyName),channel) ;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!val.Equals(GetCompInVec4(mats[i].GetVector(propertyName),channel)) )
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
public void DrawVector4Component(string label, string propertyName, string channel, bool isSlider,float minValue = 0,float maxValue = 1,
|
|
|
|
|
|
string rangeVecPropName = null, float powerSlider = 1, float multiplier = 1,
|
|
|
|
|
|
bool isReciprocal = false, Action<float,bool> drawBlock = null, Action<float,bool> drawEndChangeCheckBlock = null)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
bool hasMixedValue = Vector4ComponentHasMixedValue(propertyName, channel);
|
|
|
|
|
|
(string, string) nameTuple = (label, propertyName);
|
2025-07-21 05:42:20 -04:00
|
|
|
|
Vector4 vec = GetProperty(propertyName).vectorValue;
|
|
|
|
|
|
float f = GetCompInVec4(vec, channel);
|
2025-08-27 21:45:18 -04:00
|
|
|
|
Vector4 rangeVec = Vector4.zero;
|
|
|
|
|
|
bool isCustomedRange = rangeVecPropName != null;
|
|
|
|
|
|
if (isCustomedRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
rangeVec = GetProperty(rangeVecPropName).vectorValue;
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
f *= multiplier;
|
|
|
|
|
|
if (isReciprocal) f = 1 / f;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
EditorGUI.BeginChangeCheck();
|
2025-08-27 21:45:18 -04:00
|
|
|
|
bool propIsAnimated = IsPropertyAnimated(propertyName, channel);
|
2025-07-21 05:42:20 -04:00
|
|
|
|
if (isSlider)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (powerSlider > 1)
|
|
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
if (propIsAnimated) GUI.backgroundColor = animatedBackgroundColor;
|
|
|
|
|
|
f = PowerSlider(EditorGUILayout.GetControlRect(new GUILayoutOption[] { GUILayout.Height(18) }),
|
|
|
|
|
|
new GUIContent(label), f, minValue, maxValue, powerSlider);
|
|
|
|
|
|
GUI.backgroundColor = defaultBackgroundColor;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
if (isCustomedRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
DrawSlider(label,ref f,ref rangeVec.x,ref rangeVec.y,hasMixedValue,rangeVecPropName,propIsAnimated);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
DrawSlider(label,ref f,ref minValue,ref maxValue,hasMixedValue,propIsAnimated:propIsAnimated);
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
EditorGUI.showMixedValue = hasMixedValue;
|
|
|
|
|
|
if(propIsAnimated) GUI.backgroundColor = animatedBackgroundColor;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
f = EditorGUILayout.FloatField(label, f);
|
2025-08-27 21:45:18 -04:00
|
|
|
|
GUI.backgroundColor = defaultBackgroundColor;
|
|
|
|
|
|
EditorGUI.showMixedValue = false;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (isReciprocal) f = 1 / f;
|
|
|
|
|
|
f /= multiplier;
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
Action floatVecEndChangeCheck = () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
int id= Shader.PropertyToID(propertyName);
|
|
|
|
|
|
for (int i = 0; i < mats.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector4 val = mats[i].GetVector(id);
|
|
|
|
|
|
val = SetCompInVec4(val, channel, f);
|
|
|
|
|
|
if (mats.Count == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
GetProperty(propertyName).vectorValue = val;//为了K动画,多选不能K动画。
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
mats[i].SetVector(id, val);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (isCustomedRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
mats[i].SetVector(rangeVecPropName, rangeVec);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
drawEndChangeCheckBlock?.Invoke(f, hasMixedValue);
|
|
|
|
|
|
ResetTool.CheckOnValueChange(nameTuple);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
floatVecEndChangeCheck();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
|
|
|
|
|
|
ResetTool.DrawResetModifyButton(new Rect(),nameTuple,
|
|
|
|
|
|
resetCallBack:()=>
|
|
|
|
|
|
{
|
|
|
|
|
|
f = GetCompDefaultValueInVec4(propertyName, channel);
|
|
|
|
|
|
if (isCustomedRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
rangeVec = shader.GetPropertyDefaultVectorValue(ShaderPropertyPacksDic[rangeVecPropName].index);
|
|
|
|
|
|
}
|
|
|
|
|
|
floatVecEndChangeCheck();
|
|
|
|
|
|
},onValueChangedCallBack:floatVecEndChangeCheck,
|
|
|
|
|
|
checkHasModifyOnValueChange: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
bool isEqual = Mathf.Approximately(GetCompInVec4(mats[0].GetVector(propertyName), channel), GetCompDefaultValueInVec4(propertyName, channel));
|
|
|
|
|
|
if (isCustomedRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
isEqual &= RangePropIsDefaultValue(rangeVecPropName);
|
|
|
|
|
|
}
|
|
|
|
|
|
return !isEqual;
|
|
|
|
|
|
},
|
|
|
|
|
|
checkHasMixedValueOnValueChange: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
bool hasMixedValue = Vector4ComponentHasMixedValue(propertyName, channel);
|
|
|
|
|
|
if (isCustomedRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
RangeVecHasMixedValue(rangeVecPropName, out bool minValueHasMixed, out bool maxValueHasMixed);
|
|
|
|
|
|
hasMixedValue |= minValueHasMixed;
|
|
|
|
|
|
hasMixedValue |= maxValueHasMixed;
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
return hasMixedValue;
|
|
|
|
|
|
});
|
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
|
|
|
|
|
|
|
|
drawBlock?.Invoke(f,hasMixedValue);
|
|
|
|
|
|
ResetTool.EndResetModifyButtonScope();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
EditorGUI.showMixedValue = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void DrawVector4XYZComponet(string label, string propertyName, Action<Vector3> drawBlock = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUI.showMixedValue = GetProperty(propertyName).hasMixedValue;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
(string, string) nameTuple = (label, propertyName);
|
2025-07-21 05:42:20 -04:00
|
|
|
|
Vector4 originVec = GetProperty(propertyName).vectorValue;
|
|
|
|
|
|
Vector3 vec = originVec;
|
|
|
|
|
|
EditorGUI.BeginChangeCheck();
|
2025-08-27 21:45:18 -04:00
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
vec = EditorGUILayout.Vector3Field(label, vec);
|
2025-08-27 21:45:18 -04:00
|
|
|
|
EditorGUI.showMixedValue = false;
|
|
|
|
|
|
Action drawEndChangeCheck = () =>
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
|
|
|
|
|
GetProperty(propertyName).vectorValue = new Vector4(vec.x, vec.y, vec.z, originVec.w);
|
2025-08-27 21:45:18 -04:00
|
|
|
|
ResetTool.CheckOnValueChange(nameTuple);
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
|
|
|
|
{
|
|
|
|
|
|
drawEndChangeCheck();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
|
|
|
|
|
|
ResetTool.DrawResetModifyButton(new Rect(),nameTuple,ShaderPropertyPacksDic[propertyName],resetAction: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
vec = GetProperty(propertyName).vectorValue;
|
|
|
|
|
|
},onValueChangedCallBack:drawEndChangeCheck,vectorValeType:VectorValeType.XYZ);
|
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
drawBlock?.Invoke(vec);
|
2025-08-27 21:45:18 -04:00
|
|
|
|
ResetTool.EndResetModifyButtonScope();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public enum SamplerWarpMode
|
|
|
|
|
|
{
|
|
|
|
|
|
Repeat,
|
|
|
|
|
|
Clamp,
|
|
|
|
|
|
RepeatX_ClampY,
|
|
|
|
|
|
ClampX_RepeatY
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Rect GetRectAfterLabelWidth(Rect rect, bool ignoreIndent = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
Rect rectAfterLabelWidth = MaterialEditor.GetRectAfterLabelWidth(rect); //右边缘是准的。
|
|
|
|
|
|
Rect leftAlignedFieldRect = MaterialEditor.GetLeftAlignedFieldRect(rect); //左边缘是准的,实际有2f空隙。
|
|
|
|
|
|
float x = leftAlignedFieldRect.x + 2f;
|
|
|
|
|
|
float width = rectAfterLabelWidth.x + rectAfterLabelWidth.width - x;
|
|
|
|
|
|
|
|
|
|
|
|
var newRec = new Rect(x, rectAfterLabelWidth.y, width, rectAfterLabelWidth.height);
|
|
|
|
|
|
|
|
|
|
|
|
if (ignoreIndent)
|
|
|
|
|
|
{
|
|
|
|
|
|
float indent = (float)EditorGUI.indentLevel * 15f;
|
|
|
|
|
|
newRec.x -= indent;
|
|
|
|
|
|
newRec.width += indent;
|
|
|
|
|
|
}
|
|
|
|
|
|
return newRec;
|
|
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
public void DrawTextureFoldOut(int foldOutFlagBit,int foldOutFlagIndex,int animBoolIndex,string label, string texturePropertyName,
|
|
|
|
|
|
string colorPropertyName = null, bool drawScaleOffset = true, bool drawWrapMode = false,
|
|
|
|
|
|
int flagBitsName = 0, int flagIndex = 2, Action<MaterialProperty> drawBlock = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool foldOutState = shaderFlags[0].CheckFlagBits(foldOutFlagBit, index: foldOutFlagIndex);
|
|
|
|
|
|
AnimBool animBool = GetAnimBool(foldOutFlagBit, animBoolIndex, foldOutFlagIndex);
|
|
|
|
|
|
animBool.target = foldOutState;
|
|
|
|
|
|
DrawTextureFoldOut(ref animBool, label, texturePropertyName, colorPropertyName, drawScaleOffset,
|
|
|
|
|
|
drawWrapMode, flagBitsName, flagIndex, drawBlock);
|
|
|
|
|
|
foldOutState = animBool.target;
|
|
|
|
|
|
if (foldOutState)
|
|
|
|
|
|
{
|
|
|
|
|
|
shaderFlags[0].SetFlagBits(foldOutFlagBit, index: foldOutFlagIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
shaderFlags[0].ClearFlagBits(foldOutFlagBit, index: foldOutFlagIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
|
|
|
|
|
public void DrawTextureFoldOut(ref AnimBool foldOutAnimBool, string label, string texturePropertyName,
|
|
|
|
|
|
string colorPropertyName = null, bool drawScaleOffset = true, bool drawWrapMode = false,
|
2025-08-27 21:45:18 -04:00
|
|
|
|
int wrapModeFlagBitsName = 0, int flagIndex = 2, Action<MaterialProperty> drawBlock = null)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
// EditorGUILayout.BeginHorizontal();
|
|
|
|
|
|
// var rect = EditorGUILayout.GetControlRect(false,68f);//MaterialEditor.GetTextureFieldHeight() => 64f;
|
|
|
|
|
|
// var foldoutRect = new Rect(rect.x, rect.y, rect.width , rect.height);
|
|
|
|
|
|
// var textureThumbnialRect = new Rect(rect.x , rect.y, rect.width, rect.height);
|
|
|
|
|
|
// Texture texture = matEditor.TextureProperty(textureThumbnialRect,GetProperty(texturePropertyName), label, drawScaleOffset);
|
|
|
|
|
|
Texture texture = TextureProperty(GetProperty(texturePropertyName), label, drawScaleOffset);
|
|
|
|
|
|
// EditorGUILayout.EndHorizontal();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
|
|
|
|
|
if (colorPropertyName != null)
|
|
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
// Rect colorPropRect = GetRectAfterLabelWidth(rect, true);
|
2025-07-21 05:42:20 -04:00
|
|
|
|
// colorPropRect.x -= EditorGUI.indentLevel
|
2025-08-27 21:45:18 -04:00
|
|
|
|
// EditorGUI.indentLevel++;
|
|
|
|
|
|
// Rect colorPropRect = EditorGUILayout.GetControlRect(false);
|
|
|
|
|
|
// Color color = matEditor.ColorProperty(colorPropRect, GetProperty(colorPropertyName), "");
|
|
|
|
|
|
ColorProperty("",colorPropertyName,true);
|
|
|
|
|
|
// EditorGUI.indentLevel--;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
var foldoutRect = EditorGUILayout.GetControlRect(false);//MaterialEditor.GetTextureFieldHeight() => 64f;
|
|
|
|
|
|
Rect labelRect = foldoutRect;
|
|
|
|
|
|
labelRect.width = EditorGUIUtility.labelWidth;
|
|
|
|
|
|
EditorGUI.LabelField(labelRect, label+"相关功能", EditorStyles.boldLabel);
|
|
|
|
|
|
foldOutAnimBool.target = EditorGUI.Foldout(foldoutRect, foldOutAnimBool.target, "", true);
|
2025-07-21 05:42:20 -04:00
|
|
|
|
float faded = foldOutAnimBool.faded;
|
|
|
|
|
|
if (faded == 0) faded = 0.00001f;
|
|
|
|
|
|
EditorGUILayout.BeginFadeGroup(faded);
|
|
|
|
|
|
EditorGUI.BeginDisabledGroup(texture == null);
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
DrawAfterTexture(true, label, texturePropertyName, drawWrapMode, wrapModeFlagBitsName, flagIndex,
|
2025-07-21 05:42:20 -04:00
|
|
|
|
drawBlock);
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.EndDisabledGroup();
|
|
|
|
|
|
EditorGUILayout.EndFadeGroup();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void DrawTexture(string label, string texturePropertyName, string colorPropertyName = null,
|
2025-08-27 21:45:18 -04:00
|
|
|
|
bool drawScaleOffset = true, bool drawWrapMode = false, int wrapModeFlagBitsName = 0, int flagIndex = 2,
|
|
|
|
|
|
Action<MaterialProperty> drawBlock = null)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
|
|
|
|
|
bool hasTexture = mats[0].GetTexture(texturePropertyName) != null;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
Texture texture = TextureProperty(GetProperty(texturePropertyName), label, drawScaleOffset);
|
|
|
|
|
|
if (colorPropertyName != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
ColorProperty("",colorPropertyName,true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DrawAfterTexture(hasTexture, label, texturePropertyName, drawWrapMode, wrapModeFlagBitsName,
|
2025-07-21 05:42:20 -04:00
|
|
|
|
flagIndex, drawBlock);
|
|
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
|
|
|
|
|
|
Texture TextureProperty(MaterialProperty textureProperty, string label, bool drawScaleOffset)
|
|
|
|
|
|
{
|
|
|
|
|
|
ShaderPropertyPack texturePropertyPack = ShaderPropertyPacksDic[textureProperty.name];
|
|
|
|
|
|
if (!GUI.enabled && isClearUnUsedTexture&&textureProperty.textureValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("清除掉贴图:"+textureProperty.name,textureProperty.textureValue);
|
|
|
|
|
|
texturePropertyPack.property.textureValue = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
float indentWidth = 15f;
|
|
|
|
|
|
float currentIndentWidth = EditorGUI.indentLevel * indentWidth;
|
|
|
|
|
|
float singleLineHeight = EditorGUIUtility.singleLineHeight;
|
|
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
|
|
|
|
EditorGUILayout.GetControlRect(GUILayout.Width(EditorGUI.indentLevel * indentWidth));
|
|
|
|
|
|
float textureFieldHeight = 3*singleLineHeight;
|
|
|
|
|
|
var textureRect = EditorGUILayout.GetControlRect(GUILayout.Height(textureFieldHeight),GUILayout.Width(textureFieldHeight));
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.BeginVertical();
|
|
|
|
|
|
var textureLabelRect = EditorGUILayout.GetControlRect();
|
|
|
|
|
|
textureLabelRect.x -= currentIndentWidth;
|
|
|
|
|
|
textureLabelRect.width += currentIndentWidth;
|
|
|
|
|
|
EditorGUI.LabelField(textureLabelRect,label,EditorStyles.boldLabel);
|
|
|
|
|
|
|
|
|
|
|
|
var textureResetButtonRect = textureLabelRect;
|
|
|
|
|
|
textureResetButtonRect.x += textureResetButtonRect.width;
|
|
|
|
|
|
textureResetButtonRect.x -= ResetTool.ResetButtonSize;
|
|
|
|
|
|
textureResetButtonRect.width = ResetTool.ResetButtonSize;
|
|
|
|
|
|
|
|
|
|
|
|
float tillingOffsetLabelWidth = 30f;
|
|
|
|
|
|
Rect tillingRect = EditorGUILayout.GetControlRect();
|
|
|
|
|
|
Rect tillingVec2Rect = tillingRect;
|
|
|
|
|
|
tillingVec2Rect.x += tillingOffsetLabelWidth;
|
|
|
|
|
|
tillingVec2Rect.width -= tillingOffsetLabelWidth;
|
|
|
|
|
|
tillingVec2Rect.width -= ResetTool.ResetButtonSize;
|
|
|
|
|
|
tillingVec2Rect.width -= 2f;
|
|
|
|
|
|
Rect tillingResetButtonRect = tillingRect;
|
|
|
|
|
|
tillingResetButtonRect.x = tillingResetButtonRect.x + tillingResetButtonRect.width - ResetTool.ResetButtonSize;
|
|
|
|
|
|
tillingResetButtonRect.width = ResetTool.ResetButtonSize;
|
|
|
|
|
|
Rect offsetRect = EditorGUILayout.GetControlRect();
|
|
|
|
|
|
Rect offsetVec2Rect = offsetRect;
|
|
|
|
|
|
offsetVec2Rect.x += tillingOffsetLabelWidth;
|
|
|
|
|
|
offsetVec2Rect.width -= tillingOffsetLabelWidth;
|
|
|
|
|
|
offsetVec2Rect.width -= ResetTool.ResetButtonSize;
|
|
|
|
|
|
offsetVec2Rect.width -= 2f;
|
|
|
|
|
|
Rect offsetResetButtonRect = offsetRect;
|
|
|
|
|
|
offsetResetButtonRect.x = offsetResetButtonRect.x + offsetResetButtonRect.width - ResetTool.ResetButtonSize;
|
|
|
|
|
|
offsetResetButtonRect.width = ResetTool.ResetButtonSize;
|
|
|
|
|
|
EditorGUILayout.EndVertical();
|
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
|
|
|
|
|
|
|
|
Texture texture = textureProperty.textureValue;
|
|
|
|
|
|
Action drawTextureEndChangeCheck = () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
textureProperty.textureValue = texture;
|
|
|
|
|
|
ResetTool.CheckOnValueChange((label,texturePropertyPack.property.name));
|
|
|
|
|
|
};
|
|
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
|
|
texture = (Texture)EditorGUI.ObjectField(textureRect,texture,typeof(Texture2D));
|
|
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
|
|
|
|
{
|
|
|
|
|
|
drawTextureEndChangeCheck();
|
|
|
|
|
|
}
|
|
|
|
|
|
ResetTool.DrawResetModifyButton(textureResetButtonRect,(label,texturePropertyPack.name),texturePropertyPack,resetAction: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
texture = null;
|
|
|
|
|
|
},onValueChangedCallBack:drawTextureEndChangeCheck);
|
|
|
|
|
|
ResetTool.EndResetModifyButtonScope();
|
|
|
|
|
|
|
|
|
|
|
|
if (drawScaleOffset)
|
|
|
|
|
|
{
|
|
|
|
|
|
DrawScaleOffset(texturePropertyPack, tillingRect, tillingVec2Rect, tillingResetButtonRect, offsetRect,
|
|
|
|
|
|
offsetVec2Rect, offsetResetButtonRect);
|
|
|
|
|
|
}
|
|
|
|
|
|
return texture;
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
static float indent => (float) EditorGUI.indentLevel * 15f;
|
|
|
|
|
|
public void TextureScaleOffsetProperty(string texturePropertyName)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
ShaderPropertyPack texturePropertyPack = ShaderPropertyPacksDic[texturePropertyName];
|
|
|
|
|
|
// EditorGUILayout.BeginHorizontal();
|
|
|
|
|
|
Rect tillingRect = EditorGUILayout.GetControlRect();
|
|
|
|
|
|
// EditorGUILayout.EndHorizontal();
|
|
|
|
|
|
Rect tillingLabelRect = new Rect(tillingRect.x + indent, tillingRect.y, EditorGUIUtility.labelWidth - indent, tillingRect.height);
|
|
|
|
|
|
tillingLabelRect.width = EditorGUIUtility.labelWidth;
|
|
|
|
|
|
Rect tillingVec2Rect = tillingRect;
|
|
|
|
|
|
tillingVec2Rect.x += tillingLabelRect.width;
|
|
|
|
|
|
tillingVec2Rect.x -= indent;
|
|
|
|
|
|
tillingVec2Rect.width -= 3f;
|
|
|
|
|
|
tillingVec2Rect.width -= tillingLabelRect.width;
|
|
|
|
|
|
tillingVec2Rect.width += indent;
|
|
|
|
|
|
tillingVec2Rect.width -= ResetTool.ResetButtonSize;
|
|
|
|
|
|
Rect tillingResetButtonRect = tillingRect;
|
|
|
|
|
|
tillingResetButtonRect.x = tillingResetButtonRect.x + tillingResetButtonRect.width - ResetTool.ResetButtonSize;
|
|
|
|
|
|
tillingResetButtonRect.width = ResetTool.ResetButtonSize;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Rect offsetRect = EditorGUILayout.GetControlRect();
|
|
|
|
|
|
Rect offsetLabelRect = new Rect(offsetRect.x + indent, offsetRect.y, EditorGUIUtility.labelWidth - indent, offsetRect.height);
|
|
|
|
|
|
offsetLabelRect.width = EditorGUIUtility.labelWidth;
|
|
|
|
|
|
Rect offsetVec2Rect = offsetRect;
|
|
|
|
|
|
offsetVec2Rect.x += offsetLabelRect.width;
|
|
|
|
|
|
offsetVec2Rect.x -= indent;
|
|
|
|
|
|
offsetVec2Rect.width -= 3f;
|
|
|
|
|
|
offsetVec2Rect.width -= offsetLabelRect.width;
|
|
|
|
|
|
offsetVec2Rect.width += indent;
|
|
|
|
|
|
offsetVec2Rect.width -= ResetTool.ResetButtonSize;
|
|
|
|
|
|
Rect offsetResetButtonRect = offsetRect;
|
|
|
|
|
|
offsetResetButtonRect.x = offsetResetButtonRect.x + offsetResetButtonRect.width - ResetTool.ResetButtonSize;
|
|
|
|
|
|
offsetResetButtonRect.width = ResetTool.ResetButtonSize;
|
|
|
|
|
|
|
|
|
|
|
|
DrawScaleOffset(texturePropertyPack,tillingLabelRect,tillingVec2Rect,tillingResetButtonRect,offsetLabelRect,offsetVec2Rect,offsetResetButtonRect);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void DrawScaleOffset(ShaderPropertyPack texturePropertyPack, Rect tillingRect, Rect tillingVec2Rect,
|
|
|
|
|
|
Rect tillingResetButtonRect, Rect offsetRect, Rect offsetVec2Rect, Rect offsetResetButtonRect)
|
|
|
|
|
|
{
|
|
|
|
|
|
MaterialProperty textureProperty = texturePropertyPack.property;
|
|
|
|
|
|
Vector4 tillingOffset = textureProperty.textureScaleAndOffset;
|
|
|
|
|
|
string tillingLabel = "Tilling";
|
|
|
|
|
|
var tillingTuple = (tillingLabel, textureProperty.name + "_ST");
|
|
|
|
|
|
GUI.Label(tillingRect,tillingLabel);
|
|
|
|
|
|
Vector2 tilling = new Vector2(tillingOffset.x, tillingOffset.y);
|
|
|
|
|
|
Action drawTillingEndChangeCheck = () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
tillingOffset.x = tilling.x;
|
|
|
|
|
|
tillingOffset.y = tilling.y;
|
|
|
|
|
|
textureProperty.textureScaleAndOffset = tillingOffset;
|
|
|
|
|
|
ResetTool.CheckOnValueChange(tillingTuple);
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
|
|
if (IsPropertyAnimated(tillingTuple.Item2, "x","y") )
|
|
|
|
|
|
{
|
|
|
|
|
|
GUI.backgroundColor = animatedBackgroundColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
tilling = EditorGUI.Vector2Field(tillingVec2Rect, "", tilling);
|
|
|
|
|
|
GUI.backgroundColor = defaultBackgroundColor;
|
|
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
|
|
|
|
{
|
|
|
|
|
|
drawTillingEndChangeCheck();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ResetTool.DrawResetModifyButton(tillingResetButtonRect,tillingTuple,texturePropertyPack,resetAction: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
tilling = Vector2.one;
|
|
|
|
|
|
},onValueChangedCallBack:drawTillingEndChangeCheck,VectorValeType.Tilling);
|
|
|
|
|
|
ResetTool.EndResetModifyButtonScope();
|
|
|
|
|
|
|
|
|
|
|
|
string offsetLabel = "Offset";
|
|
|
|
|
|
var offsetTuple = (offsetLabel, textureProperty.name + "_ST");
|
|
|
|
|
|
GUI.Label(offsetRect,offsetLabel);
|
|
|
|
|
|
Vector2 offset = new Vector2(tillingOffset.z, tillingOffset.w);
|
|
|
|
|
|
Action drawOffsetEndChangeCheck = () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
tillingOffset.z = offset.x;
|
|
|
|
|
|
tillingOffset.w = offset.y;
|
|
|
|
|
|
textureProperty.textureScaleAndOffset = tillingOffset;
|
|
|
|
|
|
ResetTool.CheckOnValueChange(offsetTuple);
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
|
|
if (IsPropertyAnimated(offsetTuple.Item2, "z","w"))
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
GUI.backgroundColor = animatedBackgroundColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
offset = EditorGUI.Vector2Field(offsetVec2Rect, "", offset);
|
|
|
|
|
|
GUI.backgroundColor = defaultBackgroundColor;
|
|
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
|
|
|
|
{
|
|
|
|
|
|
drawOffsetEndChangeCheck();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ResetTool.DrawResetModifyButton(offsetResetButtonRect,offsetTuple,texturePropertyPack,resetAction: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
offset = Vector2.zero;
|
|
|
|
|
|
},onValueChangedCallBack:drawOffsetEndChangeCheck,VectorValeType.Offset);
|
|
|
|
|
|
ResetTool.EndResetModifyButtonScope();
|
|
|
|
|
|
}
|
|
|
|
|
|
bool WrapModeFlagHasMixedValue(int wrapModeFlagBitsName, int flagIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
int tmpWrapMode = 0;
|
|
|
|
|
|
for (int i = 0; i < shaderFlags.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (i == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
tmpWrapMode = GetWrapModeFlagValue(wrapModeFlagBitsName,flagIndex,shaderFlags[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
if (!tmpWrapMode.Equals(GetWrapModeFlagValue(wrapModeFlagBitsName, flagIndex, shaderFlags[i])))
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
return true;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int GetWrapModeFlagValue(int wrapModeFlagBitsName, int flagIndex,ShaderFlagsBase shaderFlag)
|
|
|
|
|
|
{
|
|
|
|
|
|
int tmpWrapMode = shaderFlag.CheckFlagBits(wrapModeFlagBitsName, index: flagIndex) ? 1 : 0;
|
|
|
|
|
|
tmpWrapMode = shaderFlag.CheckFlagBits(wrapModeFlagBitsName << 16, index: flagIndex)
|
|
|
|
|
|
? tmpWrapMode + 2
|
|
|
|
|
|
: tmpWrapMode;
|
|
|
|
|
|
return tmpWrapMode;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SetWrapModeFlagValue(int wrapModeFlagBitsName, int flagIndex,int wrapModeValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < shaderFlags.Length; i++)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
switch (wrapModeValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 0:
|
|
|
|
|
|
shaderFlags[i].ClearFlagBits(wrapModeFlagBitsName, index: flagIndex);
|
|
|
|
|
|
shaderFlags[i].ClearFlagBits(wrapModeFlagBitsName << 16, index: flagIndex);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
shaderFlags[i].SetFlagBits(wrapModeFlagBitsName, index: flagIndex);
|
|
|
|
|
|
shaderFlags[i].ClearFlagBits(wrapModeFlagBitsName << 16, index: flagIndex);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
shaderFlags[i].ClearFlagBits(wrapModeFlagBitsName, index: flagIndex);
|
|
|
|
|
|
shaderFlags[i].SetFlagBits(wrapModeFlagBitsName << 16, index: flagIndex);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
|
|
|
shaderFlags[i].SetFlagBits(wrapModeFlagBitsName, index: flagIndex);
|
|
|
|
|
|
shaderFlags[i].SetFlagBits(wrapModeFlagBitsName << 16, index: flagIndex);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
public void DrawWrapMode(string texturelabel,int wrapModeFlagBitsName = 0, int flagIndex = 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool hasMixedValue = WrapModeFlagHasMixedValue(wrapModeFlagBitsName, flagIndex);
|
|
|
|
|
|
EditorGUI.showMixedValue = hasMixedValue;
|
|
|
|
|
|
string wrapLabel = texturelabel + "循环模式";
|
|
|
|
|
|
(string, string) wrapNameTuple = (wrapLabel, "");
|
|
|
|
|
|
|
|
|
|
|
|
int tmpWrapMode = GetWrapModeFlagValue(wrapModeFlagBitsName, flagIndex,shaderFlags[0]);
|
|
|
|
|
|
Action onWrapModeEndChangeCheck = () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
SetWrapModeFlagValue(wrapModeFlagBitsName, flagIndex, tmpWrapMode);
|
|
|
|
|
|
hasMixedValue = WrapModeFlagHasMixedValue(wrapModeFlagBitsName, flagIndex);
|
|
|
|
|
|
ResetTool.CheckOnValueChange(wrapNameTuple);
|
|
|
|
|
|
};
|
|
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
|
|
|
|
tmpWrapMode = EditorGUILayout.Popup(new GUIContent(wrapLabel), tmpWrapMode,
|
|
|
|
|
|
Enum.GetNames(typeof(SamplerWarpMode)));
|
|
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
|
|
|
|
{
|
|
|
|
|
|
onWrapModeEndChangeCheck();
|
|
|
|
|
|
}
|
|
|
|
|
|
ResetTool.DrawResetModifyButton(new Rect(),wrapNameTuple,resetCallBack: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
tmpWrapMode = 0;
|
|
|
|
|
|
},onValueChangedCallBack:onWrapModeEndChangeCheck,() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
bool hasModified = GetWrapModeFlagValue(wrapModeFlagBitsName, flagIndex,shaderFlags[0]) != 0 ? true : false;
|
|
|
|
|
|
return hasModified;
|
|
|
|
|
|
}, () => WrapModeFlagHasMixedValue(wrapModeFlagBitsName, flagIndex));
|
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
|
|
ResetTool.EndResetModifyButtonScope();
|
|
|
|
|
|
}
|
|
|
|
|
|
public void DrawAfterTexture(bool hasTexture, string label, string texturePropertyName, bool drawWrapMode = false, int wrapModeFlagBitsName = 0, int flagIndex = 2,
|
|
|
|
|
|
Action<MaterialProperty> drawBlock = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// EditorGUI.indentLevel++;
|
|
|
|
|
|
EditorGUI.BeginDisabledGroup(!hasTexture);
|
|
|
|
|
|
if (drawWrapMode)
|
|
|
|
|
|
{
|
|
|
|
|
|
DrawWrapMode(label, wrapModeFlagBitsName,flagIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
drawBlock?.Invoke(GetProperty(texturePropertyName));
|
|
|
|
|
|
// EditorGUI.indentLevel--;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
EditorGUI.EndDisabledGroup();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void DrawPopUp(string label, string propertyName, string[] options, string[] toolTips = null,
|
2025-08-27 21:45:18 -04:00
|
|
|
|
Action<MaterialProperty> drawBlock = null,Action<MaterialProperty> drawOnValueChangedBlock = null,bool isSharedGlobalParent = false)
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
|
|
|
|
|
MaterialProperty property = GetProperty(propertyName);
|
|
|
|
|
|
if (property == null) return;
|
|
|
|
|
|
EditorGUI.showMixedValue = property.hasMixedValue;
|
|
|
|
|
|
|
|
|
|
|
|
float mode = property.floatValue;
|
|
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
|
|
GUIContent[] optionGUIContents = new GUIContent[options.Length];
|
|
|
|
|
|
for (int i = 0; i < optionGUIContents.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (toolTips != null && toolTips.Length == options.Length)
|
|
|
|
|
|
{
|
|
|
|
|
|
optionGUIContents[i] = new GUIContent(options[i], toolTips[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
optionGUIContents[i] = new GUIContent(options[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
|
|
|
|
|
|
Action drawOnValueChanged = () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
property.floatValue = mode;
|
|
|
|
|
|
drawOnValueChangedBlock?.Invoke(property);
|
|
|
|
|
|
ResetTool.CheckOnValueChange((label,propertyName));
|
|
|
|
|
|
};
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
mode = EditorGUILayout.Popup(new GUIContent(label), (int)mode, optionGUIContents);
|
|
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
drawOnValueChanged.Invoke();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
2025-08-27 21:45:18 -04:00
|
|
|
|
ResetTool.DrawResetModifyButton(new Rect(),(label,propertyName),ShaderPropertyPacksDic[propertyName],resetAction: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
mode = property.floatValue;
|
|
|
|
|
|
},onValueChangedCallBack:drawOnValueChanged);
|
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
drawBlock?.Invoke(property);
|
|
|
|
|
|
ResetTool.EndResetModifyButtonScope();
|
2025-07-21 05:42:20 -04:00
|
|
|
|
EditorGUI.showMixedValue = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public MaterialProperty GetProperty(string propertyName)
|
|
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
// foreach (ShaderPropertyPack pack in ShaderPropertyPacks)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// if (pack.name == propertyName)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// return pack.property;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
if (ShaderPropertyPacksDic.ContainsKey(propertyName))
|
2025-07-21 05:42:20 -04:00
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
return ShaderPropertyPacksDic[propertyName].property;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Debug.LogError("材质球" + mat.name + "找不到属性" + propertyName, mat);
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
bool RenderQueueHasMixedValue()
|
|
|
|
|
|
{
|
|
|
|
|
|
int queue = 0;
|
|
|
|
|
|
for (int i = 0; i < mats.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (i == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
queue = mats[i].renderQueue;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (queue != mats[i].renderQueue)
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
public void DrawRenderQueue(MaterialProperty queueBiasProp)
|
|
|
|
|
|
{
|
2025-08-27 21:45:18 -04:00
|
|
|
|
Rect rect = EditorGUILayout.GetControlRect();
|
|
|
|
|
|
Rect labelRect = new Rect(rect.x, rect.y, EditorGUIUtility.labelWidth, rect.height);
|
|
|
|
|
|
int queueLabelWidth = 55;
|
|
|
|
|
|
Rect queueLabelRect = new Rect(labelRect.x , labelRect.y, queueLabelWidth, rect.height);
|
|
|
|
|
|
Rect queueNumberRect = new Rect(queueLabelRect.x + queueLabelWidth , queueLabelRect.y,EditorGUIUtility.labelWidth - queueLabelWidth, rect.height);
|
|
|
|
|
|
EditorGUI.LabelField(queueLabelRect, "Queue:" );
|
|
|
|
|
|
EditorGUI.showMixedValue = RenderQueueHasMixedValue();
|
|
|
|
|
|
EditorGUI.BeginDisabledGroup(true);
|
|
|
|
|
|
EditorGUI.TextField(queueNumberRect, mats[0].renderQueue.ToString());
|
|
|
|
|
|
EditorGUI.EndDisabledGroup();
|
|
|
|
|
|
EditorGUI.showMixedValue = false;
|
|
|
|
|
|
Rect afterLabelRect = GetRectAfterLabelWidth(rect);
|
2025-07-21 05:42:20 -04:00
|
|
|
|
int QueueBias = (int)queueBiasProp.floatValue;
|
2025-08-27 21:45:18 -04:00
|
|
|
|
EditorGUI.showMixedValue = queueBiasProp.hasMixedValue;
|
|
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
|
|
QueueBias = EditorGUI.IntField(afterLabelRect, "QueueBias:", QueueBias);
|
|
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
|
|
|
|
{
|
|
|
|
|
|
queueBiasProp.floatValue = QueueBias;
|
|
|
|
|
|
}
|
|
|
|
|
|
EditorGUI.showMixedValue = false;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiLine(int i_height = 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
Rect rect = EditorGUILayout.GetControlRect(false, i_height);
|
|
|
|
|
|
rect.height = i_height;
|
|
|
|
|
|
EditorGUI.DrawRect(rect, new Color(0.5f, 0.5f, 0.5f, 0.5f));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static float PowerSlider(Rect position, GUIContent label, float value, float leftValue, float rightValue,
|
|
|
|
|
|
float power)
|
|
|
|
|
|
{
|
|
|
|
|
|
var editorGuiType = typeof(EditorGUI);
|
|
|
|
|
|
var methodInfo = editorGuiType.GetMethod(
|
|
|
|
|
|
"PowerSlider",
|
|
|
|
|
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static,
|
|
|
|
|
|
null,
|
|
|
|
|
|
new[] { typeof(Rect), typeof(GUIContent), typeof(float), typeof(float), typeof(float), typeof(float) },
|
|
|
|
|
|
null);
|
|
|
|
|
|
if (methodInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return (float)methodInfo.Invoke(null,
|
|
|
|
|
|
new object[] { position, label, value, leftValue, rightValue, power });
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return leftValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-08-27 21:45:18 -04:00
|
|
|
|
private GradientAlphaKey[] defaultGradientAlphaKey = new GradientAlphaKey[]
|
|
|
|
|
|
{ new GradientAlphaKey(1, 0), new GradientAlphaKey(1, 1) };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float RGBLuminance(Color color)
|
|
|
|
|
|
{
|
|
|
|
|
|
return 0.2126f* color.r + 0.7152f * color.g + 0.0722f * color.b;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool isUpateGradientPickerCache = false;
|
|
|
|
|
|
|
|
|
|
|
|
public void DrawGradientUndoPerformed()
|
|
|
|
|
|
{
|
|
|
|
|
|
isUpateGradientPickerCache = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
Dictionary<Gradient,bool> gradientsUpdateDic = new Dictionary<Gradient,bool>();
|
|
|
|
|
|
|
|
|
|
|
|
void GetGradientKeyCount(MaterialProperty countProperty,
|
|
|
|
|
|
MaterialProperty[] colorProperties, MaterialProperty[] alphaProperties,out int countPropertyIntValue,out int colorKeysCount,out int alphaKeysCount)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
countPropertyIntValue = countProperty.intValue;
|
|
|
|
|
|
if (colorProperties != null && alphaProperties != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
colorKeysCount = countPropertyIntValue & 0xFFFF;
|
|
|
|
|
|
alphaKeysCount = countPropertyIntValue >> 16;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
colorKeysCount = countPropertyIntValue;
|
|
|
|
|
|
alphaKeysCount = 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
bool GradientPropertyHasMixedValue(MaterialProperty countProperty,
|
|
|
|
|
|
MaterialProperty[] colorProperties = null, MaterialProperty[] alphaProperties = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GetGradientKeyCount(countProperty, colorProperties, alphaProperties,out int countPropertyIntValue, out int colorKeysCount,out int alphaKeysCount);
|
|
|
|
|
|
|
|
|
|
|
|
bool hasMixedValue = false;
|
|
|
|
|
|
hasMixedValue |= countProperty.hasMixedValue;
|
|
|
|
|
|
if (colorProperties != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
for(int i = 0; i < colorKeysCount; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
hasMixedValue |= colorProperties[i].hasMixedValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (alphaProperties != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < Mathf.CeilToInt(alphaKeysCount/2f); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
hasMixedValue |= alphaProperties[i].hasMixedValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return hasMixedValue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GetGradientConditionBool(MaterialProperty[] colorProperties,
|
|
|
|
|
|
MaterialProperty[] alphaProperties, out bool isBlackAndWhiteGradient,
|
|
|
|
|
|
out bool isNoAlphaColorGradient)
|
|
|
|
|
|
{
|
|
|
|
|
|
isBlackAndWhiteGradient = colorProperties == null && alphaProperties != null;
|
|
|
|
|
|
isNoAlphaColorGradient = colorProperties != null && alphaProperties == null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SetGradientByProperty(Gradient gradient, MaterialProperty countProperty,
|
|
|
|
|
|
MaterialProperty[] colorProperties = null, MaterialProperty[] alphaProperties = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
GetGradientConditionBool(colorProperties,alphaProperties,out bool isBlackAndWhiteGradient,out bool isNoAlphaColorGradient);
|
|
|
|
|
|
GetGradientKeyCount(countProperty, colorProperties, alphaProperties,out int countPropertyIntValue, out int colorKeysCount,out int alphaKeysCount);
|
|
|
|
|
|
|
|
|
|
|
|
if (colorProperties != null || isBlackAndWhiteGradient)
|
|
|
|
|
|
{
|
|
|
|
|
|
GradientColorKey[] colorKeys;
|
|
|
|
|
|
if (gradient.colorKeys.Length != colorKeysCount)
|
|
|
|
|
|
{
|
|
|
|
|
|
colorKeys = new GradientColorKey[colorKeysCount];
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
colorKeys = gradient.colorKeys;
|
|
|
|
|
|
}
|
|
|
|
|
|
for (int i = 0; i < colorKeysCount; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isBlackAndWhiteGradient)
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector4 vec = alphaProperties[i / 2].vectorValue;
|
|
|
|
|
|
Color c = Color.white;
|
|
|
|
|
|
if (i % 2 == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
c.r = vec.x;
|
|
|
|
|
|
c.g = vec.x;
|
|
|
|
|
|
c.b = vec.x;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
c.r = vec.z;
|
|
|
|
|
|
c.g = vec.z;
|
|
|
|
|
|
c.b = vec.z;
|
|
|
|
|
|
}
|
|
|
|
|
|
// Debug.Log(i);
|
|
|
|
|
|
// Debug.Log(c);
|
|
|
|
|
|
colorKeys[i].color = c;
|
|
|
|
|
|
colorKeys[i].time = i % 2 == 0 ? vec.y : vec.w;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Color c = colorProperties[i].colorValue;
|
|
|
|
|
|
colorKeys[i].color = c;
|
|
|
|
|
|
colorKeys[i].time = c.a;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
gradient.colorKeys = colorKeys;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (isBlackAndWhiteGradient || isNoAlphaColorGradient || alphaProperties == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
gradient.alphaKeys = defaultGradientAlphaKey;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
GradientAlphaKey[] alphaKeys;
|
|
|
|
|
|
if (gradient.alphaKeys.Length != alphaKeysCount)
|
|
|
|
|
|
{
|
|
|
|
|
|
alphaKeys = new GradientAlphaKey[alphaKeysCount];
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
alphaKeys = gradient.alphaKeys;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < alphaKeysCount ; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector4 vec = alphaProperties[i / 2].vectorValue;
|
|
|
|
|
|
if (i % 2 == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
alphaKeys[i].alpha = vec.x;
|
|
|
|
|
|
alphaKeys[i].time = vec.y;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
alphaKeys[i].alpha = vec.z;
|
|
|
|
|
|
alphaKeys[i].time = vec.w;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
gradient.alphaKeys = alphaKeys;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//如果是黑白Gradient,则取Gradient的颜色的黑白值(这样在面板上可视化比较好)
|
|
|
|
|
|
//如果既有颜色,也有Alpha。则在CountProperty上采取前16位和后16位编码。
|
|
|
|
|
|
//原则:gradient对象只是一个操作中介。取值应该直接在MatProperty上去,Set值也应该在验证合法后才能Set,不合法应该提出警告。
|
|
|
|
|
|
public void DrawGradient(Gradient gradient,bool hdr,ColorSpace colorSpace,string label,int maxCount,string countPropertyName,MaterialProperty[] colorProperties = null,MaterialProperty[] alphaProperties = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
(string,string) nameTuple = (label, countPropertyName);
|
|
|
|
|
|
if (isUpateGradientPickerCache)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var keys in gradientsUpdateDic.Keys.ToList())
|
|
|
|
|
|
{
|
|
|
|
|
|
gradientsUpdateDic[keys] = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
isUpateGradientPickerCache = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
MaterialProperty countProperty = GetProperty(countPropertyName);
|
|
|
|
|
|
Rect rect = EditorGUILayout.GetControlRect();
|
|
|
|
|
|
|
|
|
|
|
|
// var labelRect = new Rect(rect.x + 2f, rect.y, rect.width - 2f, rect.height);
|
|
|
|
|
|
// EditorGUI.LabelField(labelRect,label);
|
|
|
|
|
|
var gradientRect = rect;
|
|
|
|
|
|
gradientRect.width -= ResetTool.ResetButtonSize;
|
|
|
|
|
|
gradientRect.width -= 2f;
|
|
|
|
|
|
var gradientResetButtonRect = rect;
|
|
|
|
|
|
gradientResetButtonRect.x = gradientResetButtonRect.x + gradientResetButtonRect.width - ResetTool.ResetButtonSize;
|
|
|
|
|
|
gradientResetButtonRect.width = ResetTool.ResetButtonSize;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (gradient == null||gradientsUpdateDic[gradient])
|
|
|
|
|
|
{
|
|
|
|
|
|
if (gradient == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
gradient = new Gradient();
|
|
|
|
|
|
// gradient.colorSpace = ColorSpace.Gamma;
|
|
|
|
|
|
gradientsUpdateDic.Add(gradient,false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
gradientsUpdateDic[gradient] = false;
|
|
|
|
|
|
SetGradientByProperty(gradient,countProperty, colorProperties, alphaProperties);
|
|
|
|
|
|
|
|
|
|
|
|
GradientReflectionHelper.RefreshGradientData();
|
|
|
|
|
|
// Debug.Log("----------------SetCurrentGradient------------------");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.showMixedValue = GradientPropertyHasMixedValue(countProperty, colorProperties, alphaProperties);
|
|
|
|
|
|
GetGradientKeyCount(countProperty, colorProperties, alphaProperties,out int countPropertyIntValue, out int colorKeysCount,out int alphaKeysCount);
|
|
|
|
|
|
GetGradientConditionBool(colorProperties, alphaProperties,out bool isBlackAndWhiteGradient,out bool isNoAlphaColorGradient);
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
|
|
gradient = EditorGUI.GradientField(gradientRect, new GUIContent(label),gradient,hdr,colorSpace);
|
|
|
|
|
|
|
|
|
|
|
|
Action onGradientEndChangeCheck = () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
gradientsUpdateDic[gradient] = true;
|
|
|
|
|
|
int countPropertyValue = countPropertyIntValue;
|
|
|
|
|
|
|
|
|
|
|
|
if (colorProperties != null || isBlackAndWhiteGradient)
|
|
|
|
|
|
{
|
|
|
|
|
|
int finalColorKeysCount = gradient.colorKeys.Length;
|
|
|
|
|
|
if (finalColorKeysCount <= maxCount)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isBlackAndWhiteGradient)
|
|
|
|
|
|
{
|
|
|
|
|
|
int floatPropertyCount = Mathf.CeilToInt((float)finalColorKeysCount / (2f));
|
|
|
|
|
|
for (int i = 0; i < floatPropertyCount; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector4 vec = Vector4.zero;
|
|
|
|
|
|
vec.x = gradient.colorKeys[i*2].color.r;
|
|
|
|
|
|
vec.y = gradient.colorKeys[i*2].time;
|
|
|
|
|
|
if (i * 2 + 1 < gradient.colorKeys.Length)
|
|
|
|
|
|
{
|
|
|
|
|
|
vec.z = gradient.colorKeys[i * 2 + 1].color.r;
|
|
|
|
|
|
vec.w = gradient.colorKeys[i * 2 + 1].time;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
alphaProperties[i].vectorValue = vec;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < finalColorKeysCount; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
Color c = gradient.colorKeys[i].color;
|
|
|
|
|
|
c.a = gradient.colorKeys[i].time;
|
|
|
|
|
|
colorProperties[i].colorValue = c;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
countPropertyValue &= (0xFFFF <<16);
|
|
|
|
|
|
countPropertyValue |= finalColorKeysCount;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!(isBlackAndWhiteGradient || isNoAlphaColorGradient || alphaProperties == null))
|
|
|
|
|
|
{
|
|
|
|
|
|
int finalAlphaKeysCount = gradient.alphaKeys.Length;
|
|
|
|
|
|
if (finalAlphaKeysCount <= maxCount)
|
|
|
|
|
|
{
|
|
|
|
|
|
int floatPropertyCount = Mathf.CeilToInt((float)finalAlphaKeysCount / (2f));
|
|
|
|
|
|
for (int i = 0; i < floatPropertyCount; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector4 vec = Vector4.zero;
|
|
|
|
|
|
vec.x = gradient.alphaKeys[i*2].alpha;
|
|
|
|
|
|
vec.y = gradient.alphaKeys[i*2].time;
|
|
|
|
|
|
if (i * 2 + 1 < gradient.alphaKeys.Length)
|
|
|
|
|
|
{
|
|
|
|
|
|
vec.z = gradient.alphaKeys[i * 2 + 1].alpha;
|
|
|
|
|
|
vec.w = gradient.alphaKeys[i * 2 + 1].time;
|
|
|
|
|
|
}
|
|
|
|
|
|
alphaProperties[i].vectorValue = vec;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
countPropertyValue &= (0xFFFF);
|
|
|
|
|
|
int alphaCount = finalAlphaKeysCount << 16;
|
|
|
|
|
|
countPropertyValue |= alphaCount;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
countProperty.intValue = countPropertyValue;
|
|
|
|
|
|
ResetTool.CheckOnValueChange(nameTuple);
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
|
|
|
|
{
|
|
|
|
|
|
onGradientEndChangeCheck();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ResetTool.DrawResetModifyButton(gradientResetButtonRect,nameTuple,resetCallBack: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
ShaderPropertyPack countPropPack = ShaderPropertyPacksDic[countPropertyName];
|
|
|
|
|
|
|
|
|
|
|
|
countPropPack.property.intValue = 2;
|
|
|
|
|
|
|
|
|
|
|
|
if (colorProperties != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var colorProp in colorProperties)
|
|
|
|
|
|
{
|
|
|
|
|
|
ShaderPropertyPack colorPropPack = ShaderPropertyPacksDic[colorProp.name];
|
|
|
|
|
|
colorPropPack.property.colorValue =
|
|
|
|
|
|
shader.GetPropertyDefaultVectorValue(colorPropPack.index);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (alphaProperties != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var alphaProps in alphaProperties)
|
|
|
|
|
|
{
|
|
|
|
|
|
ShaderPropertyPack alphaPropPack = ShaderPropertyPacksDic[alphaProps.name];
|
|
|
|
|
|
alphaPropPack.property.vectorValue = shader.GetPropertyDefaultVectorValue(alphaPropPack.index);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
SetGradientByProperty(gradient,countProperty, colorProperties, alphaProperties);
|
|
|
|
|
|
|
|
|
|
|
|
},onValueChangedCallBack:onGradientEndChangeCheck,
|
|
|
|
|
|
checkHasMixedValueOnValueChange: () =>
|
|
|
|
|
|
GradientPropertyHasMixedValue(countProperty, colorProperties, alphaProperties),
|
|
|
|
|
|
checkHasModifyOnValueChange: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
bool hasModified = false;
|
|
|
|
|
|
ShaderPropertyPack countPropPack = ShaderPropertyPacksDic[countPropertyName];
|
|
|
|
|
|
|
|
|
|
|
|
bool hasCountModified = !Mathf.Approximately(mats[0].GetInteger(countPropPack.name),2);
|
|
|
|
|
|
hasModified |= hasCountModified;
|
|
|
|
|
|
if (colorProperties != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var colorProp in colorProperties)
|
|
|
|
|
|
{
|
|
|
|
|
|
ShaderPropertyPack colorPropPack = ShaderPropertyPacksDic[colorProp.name];
|
|
|
|
|
|
hasModified |= mats[0].GetVector(colorPropPack.name) !=
|
|
|
|
|
|
shader.GetPropertyDefaultVectorValue(colorPropPack.index);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (alphaProperties != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var alphaProps in alphaProperties)
|
|
|
|
|
|
{
|
|
|
|
|
|
ShaderPropertyPack alphaPropPack = ShaderPropertyPacksDic[alphaProps.name];
|
|
|
|
|
|
Vector4 vec = mats[0].GetVector(alphaPropPack.name);
|
|
|
|
|
|
Vector4 defaultVec = shader.GetPropertyDefaultVectorValue(alphaPropPack.index);
|
|
|
|
|
|
hasModified |= vec != defaultVec;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return hasModified;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
ResetTool.EndResetModifyButtonScope();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public enum VectorValeType
|
|
|
|
|
|
{
|
|
|
|
|
|
X,Y,Z,W,XY,ZW,XYZ,XYZW,Tilling,Offset,Undefine
|
2025-07-21 05:42:20 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|