닐로툰 업데이트

This commit is contained in:
Yamo4490 2025-06-18 09:49:40 +09:00
parent 4749a133f1
commit 37c21c49f7
49 changed files with 3029 additions and 966 deletions

BIN
Assets/External/NiloToonURP/CHANGELOG.md (Stored with Git LFS) vendored

Binary file not shown.

View File

@ -22,7 +22,7 @@ namespace NiloToon.NiloToonURP
private static readonly int PerMaterialEnableDepthTextureRimLightAndShadow =
Shader.PropertyToID("_PerMaterialEnableDepthTextureRimLightAndShadow");
enum NiloToonSurfaceTypePreset
public enum NiloToonSurfaceTypePreset
{
Opaque_Outline = 0,
Opaque = 1,
@ -552,7 +552,7 @@ namespace NiloToon.NiloToonURP
string[] IsSkinFinalBanNames = new string[] { };
IsSkinFinalBanNames = IsSkinFinalBanNames.Concat(IsSkinBanNames).ToArray();
//IsSkinFinalBanNames = IsSkinFinalBanNames.Concat(IsFaceBanNames).ToArray();
IsSkinFinalBanNames = IsSkinFinalBanNames.Concat(IsFaceBanNames).ToArray();
//IsSkinFinalBanNames = IsSkinFinalBanNames.Concat(IsMouthBanNames).ToArray();
//----------------------------------------------------
List<string> IsNoOutlineFinalTargetNames =
@ -1476,7 +1476,7 @@ namespace NiloToon.NiloToonURP
// ...
}
static void SetMaterialNiloToonSurfaceTypeAndProperties(Material m,
public static void SetMaterialNiloToonSurfaceTypeAndProperties(Material m,
NiloToonSurfaceTypePreset niloToonSurfaceTypePreset)
{
// fix render queue when it is out of expected range

View File

@ -19,6 +19,7 @@ namespace LWGUI
{
var shader = AssetDatabase.LoadAssetAtPath<Shader>(assetPath);
MetaDataHelper.ReleaseShaderMetadataCache(shader);
ReflectionHelper.InvalidatePropertyCache(shader);
}
}
}

View File

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using UnityEngine;
using UnityEditor;

View File

@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using LWGUI.Timeline;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
@ -13,81 +14,66 @@ namespace LWGUI
/// <summary>
/// Misc Function
/// </summary>
public class Helper
public static class Helper
{
#region Engine Misc
public static void ObsoleteWarning(string obsoleteStr, string newStr)
{
Debug.LogWarning("LWGUI: '" + obsoleteStr + "' is Obsolete! Please use '" + newStr + "'!");
}
public static bool PropertyValueEquals(MaterialProperty prop1, MaterialProperty prop2)
{
if (prop1.textureValue == prop2.textureValue
&& prop1.vectorValue == prop2.vectorValue
&& prop1.colorValue == prop2.colorValue
&& prop1.floatValue == prop2.floatValue
&& prop1.intValue == prop2.intValue
)
return true;
else
return false;
}
#region Misc
public static readonly string ProjectPath = Application.dataPath.Substring(0, Application.dataPath.Length - 6);
public static bool IsPropertyHideInInspector(MaterialProperty prop)
{
return (prop.flags & MaterialProperty.PropFlags.HideInInspector) != 0;
}
public static string GetKeyWord(string keyWord, string propName)
public static string GetKeywordName(string keyword, string propName)
{
string k;
if (string.IsNullOrEmpty(keyWord) || keyWord == "__")
if (string.IsNullOrEmpty(keyword) || keyword == "__")
{
k = propName.ToUpperInvariant() + "_ON";
}
else
{
k = keyWord.ToUpperInvariant();
k = keyword.ToUpperInvariant();
}
return k;
}
public static void SetShaderKeyWord(Object[] materials, string keyWord, bool isEnable)
public static void SetShaderKeywordEnabled(Object[] materials, string keywordName, bool isEnable)
{
if (string.IsNullOrEmpty(keyWord) || string.IsNullOrEmpty(keyWord)) return;
if (string.IsNullOrEmpty(keywordName) || string.IsNullOrEmpty(keywordName)) return;
foreach (Material m in materials)
{
// delete "_" keywords
if (keyWord == "_")
if (keywordName == "_")
{
if (m.IsKeywordEnabled(keyWord))
if (m.IsKeywordEnabled(keywordName))
{
m.DisableKeyword(keyWord);
m.DisableKeyword(keywordName);
}
continue;
}
if (m.IsKeywordEnabled(keyWord))
if (m.IsKeywordEnabled(keywordName))
{
if (!isEnable) m.DisableKeyword(keyWord);
if (!isEnable) m.DisableKeyword(keywordName);
}
else
{
if (isEnable) m.EnableKeyword(keyWord);
if (isEnable) m.EnableKeyword(keywordName);
}
}
}
public static void SetShaderKeyWord(Object[] materials, string[] keyWords, int index)
public static void SelectShaderKeyword(Object[] materials, string[] keywordNames, int index)
{
Debug.Assert(keyWords.Length >= 1 && index < keyWords.Length && index >= 0,
"KeyWords Length: " + keyWords.Length + " or Index: " + index + " Error! ");
for (int i = 0; i < keyWords.Length; i++)
Debug.Assert(keywordNames.Length >= 1 && index < keywordNames.Length && index >= 0,
"KeyWords Length: " + keywordNames.Length + " or Index: " + index + " Error! ");
for (int i = 0; i < keywordNames.Length; i++)
{
SetShaderKeyWord(materials, keyWords[i], index == i);
SetShaderKeywordEnabled(materials, keywordNames[i], index == i);
}
}
@ -161,6 +147,23 @@ namespace LWGUI
#region Math
public const double Float_Epsilon = 1e-10;
public static bool Approximately(float a, float b) => Mathf.Abs(a - b) < Float_Epsilon;
public static bool PropertyValueEquals(MaterialProperty prop1, MaterialProperty prop2)
{
if (prop1.textureValue == prop2.textureValue
&& prop1.vectorValue == prop2.vectorValue
&& prop1.colorValue == prop2.colorValue
&& Approximately(prop1.floatValue, prop2.floatValue)
&& prop1.intValue == prop2.intValue
)
return true;
else
return false;
}
public static float PowPreserveSign(float f, float p)
{
float num = Mathf.Pow(Mathf.Abs(f), p);
@ -191,6 +194,9 @@ namespace LWGUI
private static GUIStyle _guiStyle_Helpbox;
public static GUIStyle guiStyle_Helpbox => _guiStyle_Helpbox ?? new GUIStyle(EditorStyles.helpBox) { fontSize = 12 };
private static GUIStyle _guiStyle_RampSelectButton;
public static GUIStyle guiStyle_RampSelectButton => _guiStyle_RampSelectButton ?? new GUIStyle(EditorStyles.miniButton) { alignment = TextAnchor.MiddleLeft };
private static GUIStyle _guiStyles_ToolbarSearchTextFieldPopup;
public static GUIStyle guiStyles_ToolbarSearchTextFieldPopup
@ -223,7 +229,7 @@ namespace LWGUI
#endregion
#region Draw GUI for Drawer
#region Draw GUI for Drawers
// TODO: use Reflection
// copy and edit of https://github.com/GucioDevs/SimpleMinMaxSlider/blob/master/Assets/SimpleMinMaxSlider/Scripts/Editor/MinMaxSliderDrawer.cs
@ -294,10 +300,34 @@ namespace LWGUI
return toggleValue;
}
public static bool ToggleButton(Rect position, GUIContent label, bool on, GUIStyle style = null, float padding = 0)
{
var paddedRect = new Rect(position.x + padding, position.y, position.width - padding * 2, position.height);
style ??= EditorStyles.miniButton;
bool flag = GUI.Button(paddedRect, label, style);
if (Event.current.type == EventType.Repaint)
{
bool isHover = paddedRect.Contains(Event.current.mousePosition);
style.Draw(position, label, isHover, false, on, false);
}
return flag;
}
public static void DrawShaderPropertyWithErrorLabel(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor, string message)
{
var c = GUI.color;
GUI.color = Color.red;
var newLabel = $"{ label.text } ({ message })";
editor.DefaultShaderProperty(position, prop, newLabel);
GUI.color = c;
}
#endregion
#region Draw GUI for Material
#region Draw GUI for Materials
public static void DrawSplitLine()
{
@ -434,7 +464,11 @@ namespace LWGUI
for (int i = 0; i < ShaderUtil.GetPropertyCount(_copiedMaterial.shader); i++)
{
var name = ShaderUtil.GetPropertyName(_copiedMaterial.shader, i);
#if UNITY_6000_2_OR_NEWER
var type = _copiedMaterial.shader.GetPropertyType(i);
#else
var type = ShaderUtil.GetPropertyType(_copiedMaterial.shader, i);
#endif
PastePropertyValueToMaterial(material, name, name, type, valueMask);
}
if ((valueMask & (uint)CopyMaterialValueMask.Keyword) != 0)
@ -451,7 +485,11 @@ namespace LWGUI
var name = ShaderUtil.GetPropertyName(_copiedMaterial.shader, i);
if (name == srcName)
{
#if UNITY_6000_2_OR_NEWER
var type = _copiedMaterial.shader.GetPropertyType(i);
#else
var type = ShaderUtil.GetPropertyType(_copiedMaterial.shader, i);
#endif
PastePropertyValueToMaterial(material, srcName, dstName, type);
return;
}
@ -580,10 +618,10 @@ namespace LWGUI
// Build Display Mode Menu Items
var displayModeMenus = new[]
{
"Show All Advanced Properties (" + displayModeData.advancedCount + " of " + perShaderData.propStaticDatas.Count + ")",
"Show All Hidden Properties (" + displayModeData.hiddenCount + " of " + perShaderData.propStaticDatas.Count + ")",
"Show Only Modified Properties (" + perMaterialData.modifiedCount + " of " + perShaderData.propStaticDatas.Count + ")",
"Show Only Modified Properties by Group (" + perMaterialData.modifiedCount + " of " + perShaderData.propStaticDatas.Count + ")",
$"Show All Advanced Properties ({ displayModeData.advancedCount } - { perShaderData.propStaticDatas.Count })",
$"Show All Hidden Properties ({ displayModeData.hiddenCount } - { perShaderData.propStaticDatas.Count })",
$"Show Only Modified Properties ({ perMaterialData.modifiedCount } - { perShaderData.propStaticDatas.Count })",
$"Show Only Modified Properties by Group ({ perMaterialData.modifiedCount } - { perShaderData.propStaticDatas.Count })",
};
var enabled = new[] { true, true, true, true };
var separator = new bool[4];
@ -740,7 +778,7 @@ namespace LWGUI
#region Context Menu
private static void EditPresetEvent(string mode, ShaderPropertyPreset presetAsset, List<ShaderPropertyPreset.Preset> targetPresets, MaterialProperty prop, LWGUIMetaDatas metaDatas)
private static void EditPresetEvent(string mode, LwguiShaderPropertyPreset presetAsset, List<LwguiShaderPropertyPreset.Preset> targetPresets, MaterialProperty prop, LWGUIMetaDatas metaDatas)
{
if (!VersionControlHelper.Checkout(presetAsset))
{
@ -772,15 +810,15 @@ namespace LWGUI
var (perShaderData, perMaterialData, perInspectorData) = metaDatas.GetDatas();
var (propStaticData, propDynamicData) = metaDatas.GetPropDatas(prop);
var menus = new GenericMenu();
var menu = new GenericMenu();
// 2022+ Material Varant Menus
#if UNITY_2022_1_OR_NEWER
ReflectionHelper.HandleApplyRevert(menus, prop);
ReflectionHelper.HandleApplyRevert(menu, prop);
#endif
// Copy
menus.AddItem(new GUIContent("Copy"), false, () =>
menu.AddItem(new GUIContent("Copy"), false, () =>
{
_copiedMaterial = UnityEngine.Object.Instantiate(metaDatas.GetMaterial());
_copiedProps.Clear();
@ -859,20 +897,20 @@ namespace LWGUI
};
if (_copiedMaterial != null && _copiedProps.Count > 0 && GUI.enabled)
menus.AddItem(new GUIContent("Paste"), false, pasteAction);
menu.AddItem(new GUIContent("Paste"), false, pasteAction);
else
menus.AddDisabledItem(new GUIContent("Paste"));
menu.AddDisabledItem(new GUIContent("Paste"));
menus.AddSeparator("");
menu.AddSeparator("");
// Copy Display Name
menus.AddItem(new GUIContent("Copy Display Name"), false, () =>
menu.AddItem(new GUIContent("Copy Display Name"), false, () =>
{
EditorGUIUtility.systemCopyBuffer = propStaticData.displayName;
});
// Copy Property Names
menus.AddItem(new GUIContent("Copy Property Names"), false, () =>
menu.AddItem(new GUIContent("Copy Property Names"), false, () =>
{
EditorGUIUtility.systemCopyBuffer = prop.name;
foreach (var extraPropName in propStaticData.extraPropNames)
@ -896,7 +934,7 @@ namespace LWGUI
// Preset
if (GUI.enabled)
{
menus.AddSeparator("");
menu.AddSeparator("");
foreach (var activePresetData in perMaterialData.activePresetDatas)
{
// Cull self
@ -912,22 +950,38 @@ namespace LWGUI
if (activePreset.GetPropertyValue(prop.name) != null)
{
menus.AddItem(new GUIContent("Update to Preset/" + presetPropDisplayName + "/" + "All"), false, () => EditPresetEvent("Update", presetAsset, presetAsset.presets, prop, metaDatas));
menus.AddItem(new GUIContent("Update to Preset/" + presetPropDisplayName + "/" + activePreset.presetName), false, () => EditPresetEvent("Update", presetAsset, new List<ShaderPropertyPreset.Preset>(){activePreset}, prop, metaDatas));
menus.AddItem(new GUIContent("Remove from Preset/" + presetPropDisplayName + "/" + "All"), false, () => EditPresetEvent("Remove", presetAsset, presetAsset.presets, prop, metaDatas));
menus.AddItem(new GUIContent("Remove from Preset/" + presetPropDisplayName + "/" + activePreset.presetName), false, () => EditPresetEvent("Remove", presetAsset, new List<ShaderPropertyPreset.Preset>(){activePreset}, prop, metaDatas));
menu.AddItem(new GUIContent("Update to Preset/" + presetPropDisplayName + "/" + "All"), false, () => EditPresetEvent("Update", presetAsset, presetAsset.GetPresets(), prop, metaDatas));
menu.AddItem(new GUIContent("Update to Preset/" + presetPropDisplayName + "/" + activePreset.presetName), false, () => EditPresetEvent("Update", presetAsset, new List<LwguiShaderPropertyPreset.Preset>(){activePreset}, prop, metaDatas));
menu.AddItem(new GUIContent("Remove from Preset/" + presetPropDisplayName + "/" + "All"), false, () => EditPresetEvent("Remove", presetAsset, presetAsset.GetPresets(), prop, metaDatas));
menu.AddItem(new GUIContent("Remove from Preset/" + presetPropDisplayName + "/" + activePreset.presetName), false, () => EditPresetEvent("Remove", presetAsset, new List<LwguiShaderPropertyPreset.Preset>(){activePreset}, prop, metaDatas));
}
else
{
menus.AddItem(new GUIContent("Add to Preset/" + presetPropDisplayName + "/" + "All"), false, () => EditPresetEvent("Add", presetAsset, presetAsset.presets, prop, metaDatas));
menus.AddItem(new GUIContent("Add to Preset/" + presetPropDisplayName + "/" + activePreset.presetName), false, () => EditPresetEvent("Add", presetAsset, new List<ShaderPropertyPreset.Preset>(){activePreset}, prop, metaDatas));
menu.AddItem(new GUIContent("Add to Preset/" + presetPropDisplayName + "/" + "All"), false, () => EditPresetEvent("Add", presetAsset, presetAsset.GetPresets(), prop, metaDatas));
menu.AddItem(new GUIContent("Add to Preset/" + presetPropDisplayName + "/" + activePreset.presetName), false, () => EditPresetEvent("Add", presetAsset, new List<LwguiShaderPropertyPreset.Preset>(){activePreset}, prop, metaDatas));
}
}
}
// Custom
if (propStaticData.baseDrawers != null)
{
foreach (var baseDrawer in propStaticData.baseDrawers)
{
baseDrawer.GetCustomContextMenus(menu, rect, prop, metaDatas);
}
}
menus.ShowAsContext();
menu.ShowAsContext();
}
#endregion
#region Importer
// https://docs.unity3d.com/ScriptReference/TextureImporter.GetPlatformTextureSettings.html
public static string[] platformNamesForTextureSettings => new[] { "DefaultTexturePlatform", "Standalone", "Web", "iPhone", "Android", "WebGL", "Windows Store Apps", "PS4", "XboxOne", "Nintendo Switch", "tvOS" };
#endregion
}
}

View File

@ -77,7 +77,7 @@ namespace LWGUI
private static Dictionary<Shader, PerShaderCache> _perShaderCachesDic = new Dictionary<Shader, PerShaderCache>();
public static LWGUIMetaDatas BuildMetaDatas(Shader shader, Material material, MaterialEditor materialEditor, LWGUI lwgui, MaterialProperty[] props)
public static LWGUIMetaDatas BuildMetaDatas(Shader shader, Material material, MaterialEditor editor, LWGUI lwgui, MaterialProperty[] props)
{
var outDatas = new LWGUIMetaDatas();
@ -90,18 +90,18 @@ namespace LWGUI
// perMaterialData
if (!perShaderCache.perMaterialDataCachesDic.ContainsKey(material))
perShaderCache.perMaterialDataCachesDic.Add(material, new PerMaterialCache() { perMaterialData = new PerMaterialData(shader, material, props, outDatas.perShaderData) });
perShaderCache.perMaterialDataCachesDic.Add(material, new PerMaterialCache() { perMaterialData = new PerMaterialData(shader, material, editor, props, outDatas.perShaderData) });
var perMaterialCache = perShaderCache.perMaterialDataCachesDic[material];
outDatas.perMaterialData = perMaterialCache.perMaterialData;
outDatas.perMaterialData.Update(shader, material, props, outDatas.perShaderData);
outDatas.perMaterialData.Update(shader, material, editor, props, outDatas.perShaderData);
// perInspectorData
if (!perMaterialCache.perInspectorDataCachesDic.ContainsKey(lwgui))
perMaterialCache.perInspectorDataCachesDic.Add(lwgui, new PerInspectorData());
outDatas.perInspectorData = perMaterialCache.perInspectorDataCachesDic[lwgui];
outDatas.perInspectorData.Update(materialEditor);
outDatas.perInspectorData.Update(editor);
return outDatas;
}

View File

@ -7,7 +7,7 @@ namespace LWGUI
{
public class PresetHelper
{
private static Dictionary<string /*FileName*/, ShaderPropertyPreset> _loadedPresets = new Dictionary<string, ShaderPropertyPreset>();
private static Dictionary<string /*FileName*/, LwguiShaderPropertyPreset> _loadedPresets = new Dictionary<string, LwguiShaderPropertyPreset>();
private static bool _isInitComplete;
@ -25,16 +25,16 @@ namespace LWGUI
{
_loadedPresets.Clear();
_isInitComplete = false;
var GUIDs = AssetDatabase.FindAssets("t:" + typeof(ShaderPropertyPreset));
var GUIDs = AssetDatabase.FindAssets("t:" + typeof(LwguiShaderPropertyPreset));
foreach (var GUID in GUIDs)
{
var preset = AssetDatabase.LoadAssetAtPath<ShaderPropertyPreset>(AssetDatabase.GUIDToAssetPath(GUID));
var preset = AssetDatabase.LoadAssetAtPath<LwguiShaderPropertyPreset>(AssetDatabase.GUIDToAssetPath(GUID));
AddPreset(preset);
}
_isInitComplete = true;
}
public static void AddPreset(ShaderPropertyPreset preset)
public static void AddPreset(LwguiShaderPropertyPreset preset)
{
if (!preset) return;
if (!_loadedPresets.ContainsKey(preset.name))
@ -43,7 +43,7 @@ namespace LWGUI
}
}
public static ShaderPropertyPreset GetPresetFile(string presetFileName)
public static LwguiShaderPropertyPreset GetPresetAsset(string presetFileName)
{
if (string.IsNullOrEmpty(presetFileName))
return null;
@ -53,7 +53,7 @@ namespace LWGUI
if (!_loadedPresets.ContainsKey(presetFileName) || !_loadedPresets[presetFileName])
{
Debug.LogError("LWGUI: Invalid ShaderPropertyPreset: " + presetFileName + " !");
Debug.LogError("LWGUI: Invalid ShaderPropertyPreset path: " + presetFileName + " !");
return null;
}
@ -69,9 +69,9 @@ namespace LWGUI
var drawer = ReflectionHelper.GetPropertyDrawer(material.shader, prop, out _);
// Apply active preset
if (drawer != null && drawer is IBasePresetDrawer)
if (drawer != null && drawer is IPresetDrawer)
{
var activePreset = (drawer as IBasePresetDrawer).GetActivePreset(prop, PresetHelper.GetPresetFile((drawer as PresetDrawer).presetFileName));
var activePreset = (drawer as IPresetDrawer).GetActivePreset(prop, PresetHelper.GetPresetAsset((drawer as PresetDrawer).presetFileName));
if (activePreset != null)
activePreset.ApplyToDefaultMaterial(material);
}

View File

@ -14,35 +14,29 @@ namespace LWGUI
{
#region RampEditor
public static readonly string projectPath = Application.dataPath.Substring(0, Application.dataPath.Length - 6);
private static readonly GUIContent _iconAdd = new GUIContent(EditorGUIUtility.IconContent("d_Toolbar Plus").image, "Add"),
_iconEdit = new GUIContent(EditorGUIUtility.IconContent("editicon.sml").image, "Edit"),
_iconDiscard = new GUIContent(EditorGUIUtility.IconContent("d_TreeEditor.Refresh").image, "Discard"),
_iconSave = new GUIContent(EditorGUIUtility.IconContent("SaveActive").image, "Save");
public static bool RampEditor(
public static void RampEditor(
Rect buttonRect,
MaterialProperty prop,
ref LwguiGradient gradient,
ColorSpace colorSpace,
LwguiGradient.ChannelMask viewChannelMask,
LwguiGradient.GradientTimeRange timeRange,
bool isDirty,
string defaultFileName,
string rootPath,
int defaultWidth,
int defaultHeight,
out bool hasChange,
out bool doEditWhenNoGradient,
out bool doRegisterUndo,
out Texture2D newTexture,
out bool doCreate,
out bool doSave,
out bool doDiscard
out bool doDiscard,
LwguiGradientWindow.ChangeGradientCallback onChangeGradient = null
)
{
newTexture = null;
var hasChange = false;
var shouldCreate = false;
var hasNoGradient = gradient == null;
var _doEditWhenNoGradient = false;
var doOpenWindow = false;
var singleButtonWidth = buttonRect.width * 0.25f;
var editRect = new Rect(buttonRect.x + singleButtonWidth * 0, buttonRect.y, singleButtonWidth, buttonRect.height);
@ -51,14 +45,15 @@ namespace LWGUI
var discardRect = new Rect(buttonRect.x + singleButtonWidth * 3, buttonRect.y, singleButtonWidth, buttonRect.height);
// Edit button event
hasChange = false;
{
EditorGUI.BeginChangeCheck();
LwguiGradientEditorHelper.GradientEditButton(editRect, _iconEdit, gradient, colorSpace, viewChannelMask, timeRange, () =>
{
// if the current edited texture is null, create new one
if (prop.textureValue == null)
if (hasNoGradient)
{
shouldCreate = true;
_doEditWhenNoGradient = true;
Event.current.Use();
return false;
}
@ -67,47 +62,23 @@ namespace LWGUI
doOpenWindow = true;
return true;
}
});
}, onChangeGradient);
if (EditorGUI.EndChangeCheck())
{
hasChange = true;
gradient = LwguiGradientWindow.instance.lwguiGradient;
if (LwguiGradientWindow.instance)
{
gradient = LwguiGradientWindow.instance.lwguiGradient;
}
}
doRegisterUndo = doOpenWindow;
}
doEditWhenNoGradient = _doEditWhenNoGradient;
// Create button
if (GUI.Button(addRect, _iconAdd) || shouldCreate)
{
while (true)
{
if (!Directory.Exists(projectPath + rootPath))
Directory.CreateDirectory(projectPath + rootPath);
var absPath = EditorUtility.SaveFilePanel("Create New Ramp Texture", rootPath, defaultFileName, "png");
if (absPath.StartsWith(projectPath + rootPath))
{
//Create texture and save PNG
var saveUnityPath = absPath.Replace(projectPath, String.Empty);
CreateAndSaveNewGradientTexture(defaultWidth, defaultHeight, saveUnityPath, colorSpace == ColorSpace.Linear);
// VersionControlHelper.Add(saveUnityPath);
//Load created texture
newTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(saveUnityPath);
break;
}
else if (absPath != String.Empty)
{
var retry = EditorUtility.DisplayDialog("Invalid Path", "Please select the subdirectory of '" + projectPath + rootPath + "'", "Retry", "Cancel");
if (!retry) break;
}
else
{
break;
}
}
}
doCreate = GUI.Button(addRect, _iconAdd);
// Save button
{
@ -119,8 +90,6 @@ namespace LWGUI
// Discard button
doDiscard = GUI.Button(discardRect, _iconDiscard);
return hasChange;
}
public static bool HasGradient(AssetImporter assetImporter) { return assetImporter.userData.Contains("#");}
@ -174,7 +143,7 @@ namespace LWGUI
// Save texture to disk
if (doSaveToDisk)
{
var systemPath = projectPath + path;
var systemPath = Helper.ProjectPath + path;
VersionControlHelper.Checkout(path);
File.WriteAllBytes(systemPath, texture2D.EncodeToPNG());
assetImporter.SaveAndReimport();
@ -228,28 +197,42 @@ namespace LWGUI
var ramp = gradient.GetPreviewRampTexture(width, height, ColorSpace.Linear);
var png = ramp.EncodeToPNG();
var systemPath = projectPath + unityPath;
var systemPath = Helper.ProjectPath + unityPath;
File.WriteAllBytes(systemPath, png);
AssetDatabase.ImportAsset(unityPath);
SetRampTextureImporter(unityPath, true, isLinear, EncodeGradientToJSON(gradient, gradient));
return true;
}
public static void SetRampTextureImporter(string unityPath, bool isReadable = true, bool isLinear = false, string userData = null)
{
var textureImporter = AssetImporter.GetAtPath(unityPath) as TextureImporter;
if (!textureImporter)
{
Debug.LogError($"LWGUI: Can NOT get TextureImporter at path: { unityPath }");
return;
}
textureImporter.wrapMode = TextureWrapMode.Clamp;
textureImporter.isReadable = true;
textureImporter.isReadable = isReadable;
textureImporter.textureCompression = TextureImporterCompression.Uncompressed;
textureImporter.alphaSource = TextureImporterAlphaSource.FromInput;
textureImporter.mipmapEnabled = false;
textureImporter.sRGBTexture = !isLinear;
var platformTextureSettings = textureImporter.GetDefaultPlatformTextureSettings();
platformTextureSettings.format = TextureImporterFormat.RGBA32;
platformTextureSettings.textureCompression = TextureImporterCompression.Uncompressed;
textureImporter.SetPlatformTextureSettings(platformTextureSettings);
foreach (var platformName in Helper.platformNamesForTextureSettings)
{
var platformTextureSettings = textureImporter.GetPlatformTextureSettings(platformName);
platformTextureSettings.format = TextureImporterFormat.RGBA32;
textureImporter.SetPlatformTextureSettings(platformTextureSettings);
}
//Gradient data embedded in userData
textureImporter.userData = EncodeGradientToJSON(gradient, gradient);
if (userData != null)
textureImporter.userData = userData;
textureImporter.SaveAndReimport();
return true;
}
#endregion
@ -257,7 +240,7 @@ namespace LWGUI
#region RampSelector
public static void RampSelector(Rect rect, string rootPath, Action<Texture2D> switchRampMapEvent)
public static void RampMapSelectorOverride(Rect rect, MaterialProperty prop, string rootPath, RampSelectorWindow.SwitchRampMapCallback switchRampMapEvent)
{
var e = Event.current;
if (e.type == UnityEngine.EventType.MouseDown && rect.Contains(e.mousePosition))
@ -275,7 +258,20 @@ namespace LWGUI
else
return null;
}).ToArray();
RampSelectorWindow.ShowWindow(rect, rampMaps, switchRampMapEvent);
RampSelectorWindow.ShowWindow(prop, rampMaps, switchRampMapEvent);
}
}
public static void RampIndexSelectorOverride(Rect rect, MaterialProperty prop, LwguiRampAtlas rampAtlas, RampSelectorWindow.SwitchRampMapCallback switchRampMapEvent)
{
if (!rampAtlas)
return;
var e = Event.current;
if (e.type == UnityEngine.EventType.MouseDown && rect.Contains(e.mousePosition))
{
e.Use();
RampSelectorWindow.ShowWindow(prop, rampAtlas.GetTexture2Ds(LwguiGradient.ChannelMask.RGB), switchRampMapEvent);
}
}
#endregion
@ -283,16 +279,20 @@ namespace LWGUI
public class RampSelectorWindow : EditorWindow
{
public delegate void SwitchRampMapCallback(MaterialProperty prop, Texture2D newRampMap, int index);
private Texture2D[] _rampMaps;
private Vector2 _scrollPosition;
private Action<Texture2D> _switchRampMapEvent;
private MaterialProperty _prop;
private SwitchRampMapCallback _switchRampMapEvent;
public static void ShowWindow(Rect rect, Texture2D[] rampMaps, Action<Texture2D> switchRampMapEvent)
public static void ShowWindow(MaterialProperty prop, Texture2D[] rampMaps, SwitchRampMapCallback switchRampMapEvent)
{
RampSelectorWindow window = ScriptableObject.CreateInstance<RampSelectorWindow>();
window.titleContent = new GUIContent("Ramp Selector");
window.minSize = new Vector2(400, 500);
window._rampMaps = rampMaps;
window._prop = prop;
window._switchRampMapEvent = switchRampMapEvent;
window.ShowAuxWindow();
}
@ -302,19 +302,22 @@ namespace LWGUI
EditorGUILayout.BeginVertical();
_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);
foreach (Texture2D rampMap in _rampMaps)
for (int i = 0; i < _rampMaps.Length; i++)
{
var rampMap = _rampMaps[i];
EditorGUILayout.BeginHorizontal();
if (rampMap != null)
{
var guiContent = new GUIContent(rampMap.name);
var guiContent = new GUIContent($"{ i }. { rampMap.name }");
var rect = EditorGUILayout.GetControlRect();
var buttonWidth = Mathf.Min(300f, Mathf.Max(GUI.skin.button.CalcSize(guiContent).x, rect.width * 0.35f));
var buttonRect = new Rect(rect.x + rect.width - buttonWidth, rect.y, buttonWidth, rect.height);
var previewRect = new Rect(rect.x, rect.y, rect.width - buttonWidth - 3.0f, rect.height);
if (GUI.Button(buttonRect, guiContent) && _switchRampMapEvent != null)
if (GUI.Button(buttonRect, guiContent, Helper.guiStyle_RampSelectButton) && _switchRampMapEvent != null)
{
_switchRampMapEvent(rampMap);
_switchRampMapEvent(_prop, rampMap, i);
LwguiGradientWindow.CloseWindow();
Close();
}
EditorGUI.DrawPreviewTexture(previewRect, rampMap);

View File

@ -130,6 +130,7 @@ namespace LWGUI
if (DrawRevertButton(rect))
{
GUI.changed = true;
EditorGUI.FocusTextInControl(string.Empty);
DoRevertProperty(prop, metaDatas);
if (isHeader)

View File

@ -1,7 +1,6 @@
// Copyright (c) Jason Ma
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEditor.VersionControl;
@ -9,7 +8,7 @@ using UnityEngine;
namespace LWGUI
{
public class VersionControlHelper
public static class VersionControlHelper
{
public static bool isVCEnabled => Provider.enabled && Provider.isActive;
@ -99,5 +98,31 @@ namespace LWGUI
return true;
}
public static bool IsWriteable(UnityEngine.Object obj) => IsWriteable(new[] { obj });
public static bool IsWriteable(UnityEngine.Object[] objs)
{
if (objs == null)
return false;
bool isWriteable = true;
foreach (var obj in objs)
{
if (!obj)
continue;
if (!AssetDatabase.Contains(obj))
continue;
isWriteable &= AssetDatabase.IsOpenForEdit(obj);
if (!isWriteable)
break;
}
return isWriteable;
}
}
}

View File

@ -3,6 +3,7 @@
"rootNamespace": "",
"references": [
"LWGUI.Runtime",
"LWGUI.Timeline",
"Unity.InternalAPIEditorBridge.020"
],
"includePlatforms": [

View File

@ -1,4 +1,5 @@
// Copyright (c) Jason Ma
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
@ -9,7 +10,8 @@ namespace LWGUI
public class LWGUI : ShaderGUI
{
public LWGUIMetaDatas metaDatas;
public LWGUIMetaDatas metaDatas;
public bool hasChange;
public static LWGUICustomGUIEvent onDrawCustomHeader;
public static LWGUICustomGUIEvent onDrawCustomFooter;
@ -22,13 +24,18 @@ namespace LWGUI
/// <summary>
/// Called every frame when the content is updated, such as the mouse moving in the material editor
/// </summary>
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
public override void OnGUI(MaterialEditor editor, MaterialProperty[] props)
{
//-----------------------------------------------------------------------------
// Init Datas
var material = materialEditor.target as Material;
var material = editor.target as Material;
var shader = material.shader;
this.metaDatas = MetaDataHelper.BuildMetaDatas(shader, material, materialEditor, this, props);
if (hasChange)
{
OnValidate(editor.targets);
hasChange = false;
}
this.metaDatas = MetaDataHelper.BuildMetaDatas(shader, material, editor, this, props);
//-----------------------------------------------------------------------------
@ -55,7 +62,7 @@ namespace LWGUI
// Draw Properties
{
// move fields left to make rect for Revert Button
materialEditor.SetDefaultGUIWidths();
editor.SetDefaultGUIWidths();
RevertableHelper.InitRevertableGUIWidths();
// start drawing properties
@ -104,7 +111,7 @@ namespace LWGUI
EditorGUI.indentLevel = indentLevel;
}
materialEditor.SetDefaultGUIWidths();
editor.SetDefaultGUIWidths();
}
@ -116,10 +123,10 @@ namespace LWGUI
// Render settings
if (SupportedRenderingFeatures.active.editableMaterialRenderQueue)
materialEditor.RenderQueueField();
materialEditor.EnableInstancingField();
materialEditor.LightmapEmissionProperty();
materialEditor.DoubleSidedGIField();
editor.RenderQueueField();
editor.EnableInstancingField();
editor.LightmapEmissionProperty();
editor.DoubleSidedGIField();
// Custom Footer
if (onDrawCustomFooter != null)
@ -163,11 +170,14 @@ namespace LWGUI
if (propStaticData.isReadOnly) GUI.enabled = false;
Helper.BeginProperty(rect, prop, metaDatas);
Helper.DoPropertyContextMenus(rect, prop, metaDatas);
RevertableHelper.FixGUIWidthMismatch(prop.type, materialEditor);
if (propStaticData.isAdvancedHeaderProperty)
propStaticData.isExpanding = EditorGUI.Foldout(rect, propStaticData.isExpanding, string.Empty);
RevertableHelper.DrawRevertableProperty(revertButtonRect, prop, metaDatas, propStaticData.isMain || propStaticData.isAdvancedHeaderProperty);
materialEditor.ShaderProperty(rect, prop, label);
Helper.EndProperty(metaDatas, prop);
GUI.enabled = enabled;
}
@ -187,6 +197,7 @@ namespace LWGUI
public static void OnValidate(Object[] materials)
{
VersionControlHelper.Checkout(materials);
UnityEditorExtension.ApplyMaterialPropertyAndDecoratorDrawers(materials);
MetaDataHelper.ForceUpdateMaterialsMetadataCache(materials);
}
@ -197,20 +208,26 @@ namespace LWGUI
OnValidate(metaDatas?.GetMaterialEditor()?.targets);
}
// Called after edit or undo
public override void ValidateMaterial(Material material)
{
base.ValidateMaterial(material);
// Undo
if (metaDatas == null)
// Debug.Log($"ValidateMaterial {material.name}, {metaDatas}, {Event.current?.type}");
// Validate a Faked Material when select/edit a Material
if (metaDatas == null && (Event.current == null || Event.current.type == EventType.Layout))
{
OnValidate(new Object[] { material });
// Skip to avoid lag when editing large amounts of materials
}
// Undo/Edit in Timeline (EventType.Repaint)
// Note: When modifying the material in Timeline in Unity 2022, this function cannot correctly obtain the modified value.
else if (metaDatas == null)
{
MetaDataHelper.ForceUpdateMaterialMetadataCache(material);
}
// Edit
else
{
OnValidate(metaDatas);
if (!hasChange) hasChange = true;
}
}
}
} //namespace LWGUI
}

View File

@ -10,10 +10,10 @@ namespace LWGUI
{
public class PersetDynamicData
{
public ShaderPropertyPreset.Preset preset;
public LwguiShaderPropertyPreset.Preset preset;
public MaterialProperty property;
public PersetDynamicData(ShaderPropertyPreset.Preset preset, MaterialProperty property)
public PersetDynamicData(LwguiShaderPropertyPreset.Preset preset, MaterialProperty property)
{
this.preset = preset;
this.property = property;
@ -30,6 +30,7 @@ namespace LWGUI
public bool hasChildrenModified = false; // Are Children properties modified in the material?
public bool hasRevertChanged = false; // Used to call property EndChangeCheck()
public bool isShowing = true; // ShowIf() result
public bool isAnimated = false; // Material Parameter Animation preview in Timeline is activated
}
/// <summary>
@ -37,21 +38,25 @@ namespace LWGUI
/// </summary>
public class PerMaterialData
{
public Dictionary<string, PropertyDynamicData> propDynamicDatas = new Dictionary<string, PropertyDynamicData>();
public MaterialProperty[] props = null;
public Material material = null;
public List<PersetDynamicData> activePresetDatas = new List<PersetDynamicData>();
public int modifiedCount = 0;
public Dictionary<string, bool> cachedModifiedProperties = null;
public bool forceInit = true;
public Dictionary<string, PropertyDynamicData> propDynamicDatas = new Dictionary<string, PropertyDynamicData>();
public MaterialProperty[] props = null;
public Material material = null;
public Material defaultMaterialWithPresetOverride = null;
public MaterialProperty[] defaultPropertiesWithPresetOverride = null;
public List<PersetDynamicData> activePresetDatas = new List<PersetDynamicData>();
public int modifiedCount = 0;
public Dictionary<string, bool> cachedModifiedProperties = null;
public bool forceInit = true;
public PerMaterialData(Shader shader, Material material, MaterialProperty[] props, PerShaderData perShaderData)
public PerMaterialData(Shader shader, Material material, MaterialEditor editor, MaterialProperty[] props, PerShaderData perShaderData)
{
Init(shader, material, props, perShaderData);
Init(shader, material, editor, props, perShaderData);
}
public void Init(Shader shader, Material material, MaterialProperty[] props, PerShaderData perShaderData)
public void Init(Shader shader, Material material, MaterialEditor editor, MaterialProperty[] props, PerShaderData perShaderData)
{
forceInit = false;
// Reset Datas
this.props = props;
this.material = material;
@ -75,7 +80,7 @@ namespace LWGUI
{
// Apply presets to default material
var defaultMaterial = UnityEngine.Object.Instantiate(
defaultMaterialWithPresetOverride = UnityEngine.Object.Instantiate(
#if UNITY_2022_1_OR_NEWER
material.parent
? material.parent
@ -85,20 +90,20 @@ namespace LWGUI
);
foreach (var activePresetData in activePresetDatas)
activePresetData.preset.ApplyToDefaultMaterial(defaultMaterial);
activePresetData.preset.ApplyToDefaultMaterial(defaultMaterialWithPresetOverride);
var defaultProperties = MaterialEditor.GetMaterialProperties(new[] { defaultMaterial });
Debug.Assert(defaultProperties.Length == props.Length);
defaultPropertiesWithPresetOverride = MaterialEditor.GetMaterialProperties(new[] { defaultMaterialWithPresetOverride });
Debug.Assert(defaultPropertiesWithPresetOverride.Length == props.Length);
// Init propDynamicDatas
for (int i = 0; i < props.Length; i++)
{
var hasModified = !Helper.PropertyValueEquals(props[i], defaultProperties[i]);
var hasModified = !Helper.PropertyValueEquals(props[i], defaultPropertiesWithPresetOverride[i]);
if (hasModified) modifiedCount++;
propDynamicDatas.Add(props[i].name, new PropertyDynamicData()
{
property = props[i],
defualtProperty = defaultProperties[i],
defualtProperty = defaultPropertiesWithPresetOverride[i],
hasModified = hasModified
});
}
@ -158,21 +163,33 @@ namespace LWGUI
// Get ShowIf() results
ShowIfDecorator.GetShowIfResult(propStaticData, propDynamicData, this);
}
forceInit = false;
}
public void Update(Shader shader, Material material, MaterialProperty[] props, PerShaderData perShaderData)
public void Update(Shader shader, Material material, MaterialEditor editor, MaterialProperty[] props, PerShaderData perShaderData)
{
if (forceInit)
{
Init(shader, material, props, perShaderData);
return;
Init(shader, material, editor, props, perShaderData);
}
foreach (var prop in props)
else
{
propDynamicDatas[prop.name].property = prop;
foreach (var prop in props)
{
propDynamicDatas[prop.name].property = prop;
}
}
// Check animated
var renderer = editor.GetRendererForAnimationMode();
if (renderer != null)
{
forceInit = true;
foreach (var prop in props)
{
ReflectionHelper.MaterialAnimationUtility_OverridePropertyColor(prop, renderer, out var color);
if (color != Color.white)
propDynamicDatas[prop.name].isAnimated = true;
}
}
}

View File

@ -31,6 +31,9 @@ namespace LWGUI
public bool IsDefaultDisplayMode() { return !(showAllAdvancedProperties || showAllHiddenProperties || showOnlyModifiedProperties || showOnlyModifiedGroups); }
}
/// <summary>
/// The static metadata of Material Property is only related to Shader.
/// </summary>
public partial class PropertyStaticData
{
public string name = string.Empty;
@ -55,14 +58,14 @@ namespace LWGUI
public string conditionalDisplayKeyword = string.Empty; // [Group(groupName_conditionalDisplayKeyword)]
// Drawers
public IBasePresetDrawer presetDrawer = null;
public IPresetDrawer presetDrawer = null;
public List<IBaseDrawer> baseDrawers = null;
// Metadata
public List<string> extraPropNames = new List<string>(); // Other Props that have been associated
public string helpboxMessages = string.Empty;
public string tooltipMessages = string.Empty;
public ShaderPropertyPreset propertyPresetAsset = null; // The Referenced Preset Asset
public LwguiShaderPropertyPreset propertyPresetAsset = null; // The Referenced Preset Asset
public void AddExtraProperty(string propName)
{
@ -109,8 +112,8 @@ namespace LWGUI
{
var drawer = ReflectionHelper.GetPropertyDrawer(shader, prop, out var decoratorDrawers);
if (drawer is IBasePresetDrawer)
propStaticData.presetDrawer = drawer as IBasePresetDrawer;
if (drawer is IPresetDrawer)
propStaticData.presetDrawer = drawer as IPresetDrawer;
var baseDrawer = drawer as IBaseDrawer;
if (baseDrawer != null)

Binary file not shown.

Binary file not shown.

View File

@ -21,7 +21,7 @@ namespace LWGUI.Runtime.LwguiGradient
Num = 4
}
[Flags]
[Flags] // Flags Attribute must be used to support bit operations
public enum ChannelMask
{
None = 0,
@ -30,7 +30,7 @@ namespace LWGUI.Runtime.LwguiGradient
Blue = 1 << 2,
Alpha = 1 << 3,
RGB = Red | Green | Blue,
All = RGB | Alpha
All = ~0
}
public enum GradientTimeRange
@ -61,6 +61,49 @@ namespace LWGUI.Runtime.LwguiGradient
// The complete data is stored by RGBA Curves and can be converted into Texture
[SerializeField] private List<AnimationCurve> _curves;
public List<AnimationCurve> rawCurves
{
get
{
_curves ??= new List<AnimationCurve>();
if (_curves.Count < (int)Channel.Num)
{
for (int c = 0; c < (int)Channel.Num; c++)
{
if (c == _curves.Count)
_curves.Add(defaultCurve);
}
}
return _curves;
}
set => SetRgbaCurves(value);
}
public AnimationCurve redCurve
{
get => rawCurves[(int)Channel.Red] ?? defaultCurve;
set => SetCurve(value, ChannelMask.Red);
}
public AnimationCurve greenCurve
{
get => rawCurves[(int)Channel.Green] ?? defaultCurve;
set => SetCurve(value, ChannelMask.Green);
}
public AnimationCurve blueCurve
{
get => rawCurves[(int)Channel.Blue] ?? defaultCurve;
set => SetCurve(value, ChannelMask.Blue);
}
public AnimationCurve alphaCurve
{
get => rawCurves[(int)Channel.Alpha] ?? defaultCurve;
set => SetCurve(value, ChannelMask.Alpha);
}
#endregion
@ -248,7 +291,7 @@ namespace LWGUI.Runtime.LwguiGradient
if (!IsChannelIndexInMask(c, channelMask))
continue;
_curves[c].AddKey(key);
rawCurves[c].AddKey(key);
}
}
@ -261,60 +304,28 @@ namespace LWGUI.Runtime.LwguiGradient
}
}
public List<AnimationCurve> rawCurves
{
get => _curves;
set => SetRgbaCurves(value);
}
public AnimationCurve redCurve
{
get => _curves[(int)Channel.Red] ?? defaultCurve;
set => SetCurve(value, ChannelMask.Red);
}
public AnimationCurve greenCurve
{
get => _curves[(int)Channel.Green] ?? defaultCurve;
set => SetCurve(value, ChannelMask.Green);
}
public AnimationCurve blueCurve
{
get => _curves[(int)Channel.Blue] ?? defaultCurve;
set => SetCurve(value, ChannelMask.Blue);
}
public AnimationCurve alphaCurve
{
get => _curves[(int)Channel.Alpha] ?? defaultCurve;
set => SetCurve(value, ChannelMask.Alpha);
}
public Color Evaluate(float time, ChannelMask channelMask = ChannelMask.All, GradientTimeRange timeRange = GradientTimeRange.One)
{
time /= (int)timeRange;
if (channelMask == ChannelMask.Alpha)
{
var alpha = _curves[(int)Channel.Alpha].Evaluate(time);
var alpha = rawCurves[(int)Channel.Alpha].Evaluate(time);
return new Color(alpha, alpha, alpha, 1);
}
return new Color(
IsChannelIndexInMask((int)Channel.Red, channelMask) ? _curves[(int)Channel.Red].Evaluate(time) : 0,
IsChannelIndexInMask((int)Channel.Green, channelMask) ? _curves[(int)Channel.Green].Evaluate(time) : 0,
IsChannelIndexInMask((int)Channel.Blue, channelMask) ? _curves[(int)Channel.Blue].Evaluate(time) : 0,
IsChannelIndexInMask((int)Channel.Alpha, channelMask) ? _curves[(int)Channel.Alpha].Evaluate(time) : 1);
IsChannelIndexInMask((int)Channel.Red, channelMask) ? rawCurves[(int)Channel.Red].Evaluate(time) : 0,
IsChannelIndexInMask((int)Channel.Green, channelMask) ? rawCurves[(int)Channel.Green].Evaluate(time) : 0,
IsChannelIndexInMask((int)Channel.Blue, channelMask) ? rawCurves[(int)Channel.Blue].Evaluate(time) : 0,
IsChannelIndexInMask((int)Channel.Alpha, channelMask) ? rawCurves[(int)Channel.Alpha].Evaluate(time) : 1);
}
public void SetLinearTangentMode()
{
for (int c = 0; c < (int)Channel.Num; c++)
{
_curves[c].SetLinearTangents();
rawCurves[c].SetLinearTangents();
}
}
@ -336,6 +347,23 @@ namespace LWGUI.Runtime.LwguiGradient
return pixels;
}
public void GetPixels(ref Color[] outputPixels, ref int currentIndex, int width, int height, ChannelMask channelMask = ChannelMask.All)
{
if (outputPixels == null || currentIndex >= outputPixels.Length)
return;
for (var x = 0; x < width; x++)
{
var u = x / (float)width;
var col = Evaluate(u, channelMask);
for (int i = 0; i < height; i++)
{
if (currentIndex < outputPixels.Length)
outputPixels[currentIndex ++] = col;
}
}
}
public Texture2D GetPreviewRampTexture(int width = 256, int height = 1, ColorSpace colorSpace = ColorSpace.Gamma, ChannelMask channelMask = ChannelMask.All)
{
if (LwguiGradientHelper.TryGetRampPreview(this, width, height, colorSpace, channelMask, out var cachedPreview))
@ -492,7 +520,7 @@ namespace LWGUI.Runtime.LwguiGradient
public Gradient ToGradient(int maxGradientKeyCount = 8)
{
return new LwguiMergedColorCurves(_curves).ToGradient(maxGradientKeyCount);
return new LwguiMergedColorCurves(rawCurves).ToGradient(maxGradientKeyCount);
}
#endregion

View File

@ -20,11 +20,12 @@ TextureImporter:
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 1
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
@ -63,6 +64,7 @@ TextureImporter:
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
@ -75,6 +77,7 @@ TextureImporter:
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
@ -87,6 +90,7 @@ TextureImporter:
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
@ -99,6 +103,7 @@ TextureImporter:
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
@ -115,9 +120,8 @@ TextureImporter:
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
mipmapLimitGroupName:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData: '{"_curves":[{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}]}#{"_curves":[{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}]}'
assetBundleName:
assetBundleVariant:

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -1,43 +1,124 @@
// Made with Amplify Shader Editor v1.9.1.8
// Made with Amplify Shader Editor v1.9.2.2
// Available at the Unity Asset Store - http://u3d.as/y3X
Shader "Hidden"
{
Properties
{
[HDR][Header()][Header(Test Header)][Space(50)]_Color("Color", Vector) = (0,0,0,0)
[HideInInspector] __dirty( "", Int ) = 1
}
}
SubShader
{
Tags{ "RenderType" = "Opaque" "Queue" = "Geometry+0" }
Cull Back
CGPROGRAM
Tags { "RenderType"="Opaque" }
LOD 100
CGINCLUDE
#pragma target 3.0
#pragma surface surf Standard keepalpha addshadow fullforwardshadows
struct Input
{
half filler;
};
uniform float3 _Color;
void surf( Input i , inout SurfaceOutputStandard o )
{
o.Albedo = _Color;
o.Alpha = 1;
}
ENDCG
Blend Off
AlphaToMask Off
Cull Back
ColorMask RGBA
ZWrite On
ZTest LEqual
Offset 0 , 0
Pass
{
Name "Unlit"
CGPROGRAM
#ifndef UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX
//only defining to not throw compilation error over Unity 5.5
#define UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input)
#endif
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
#ifdef ASE_NEEDS_FRAG_WORLD_POSITION
float3 worldPos : TEXCOORD0;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
uniform float3 _Color;
v2f vert ( appdata v )
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
UNITY_TRANSFER_INSTANCE_ID(v, o);
float3 vertexValue = float3(0, 0, 0);
#if ASE_ABSOLUTE_VERTEX_POS
vertexValue = v.vertex.xyz;
#endif
vertexValue = vertexValue;
#if ASE_ABSOLUTE_VERTEX_POS
v.vertex.xyz = vertexValue;
#else
v.vertex.xyz += vertexValue;
#endif
o.vertex = UnityObjectToClipPos(v.vertex);
#ifdef ASE_NEEDS_FRAG_WORLD_POSITION
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
#endif
return o;
}
fixed4 frag (v2f i ) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
fixed4 finalColor;
#ifdef ASE_NEEDS_FRAG_WORLD_POSITION
float3 WorldPosition = i.worldPos;
#endif
finalColor = float4( _Color , 0.0 );
return finalColor;
}
ENDCG
}
}
Fallback "Diffuse"
CustomEditor "ASEMaterialInspector"
Fallback Off
}
/*ASEBEGIN
Version=19108
Node;AmplifyShaderEditor.StandardSurfaceOutputNode;0;-8,-15;Float;False;True;-1;2;ASEMaterialInspector;0;0;Standard;Hidden;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;Back;0;False;;0;False;;False;0;False;;0;False;;False;0;Opaque;0.5;True;True;0;False;Opaque;;Geometry;All;12;all;True;True;True;True;0;False;;False;0;False;;255;False;;255;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;2;15;10;25;False;0.5;True;0;0;False;;0;False;;0;0;False;;0;False;;0;False;;0;False;;0;False;0;0,0,0,0;VertexOffset;True;False;Cylindrical;False;True;Relative;0;;-1;-1;-1;-1;0;False;0;0;False;;-1;0;False;;0;0;0;False;0.1;False;;0;False;;False;16;0;FLOAT3;0,0,0;False;1;FLOAT3;0,0,0;False;2;FLOAT3;0,0,0;False;3;FLOAT;0;False;4;FLOAT;0;False;5;FLOAT;0;False;6;FLOAT3;0,0,0;False;7;FLOAT3;0,0,0;False;8;FLOAT;0;False;9;FLOAT;0;False;10;FLOAT;0;False;13;FLOAT3;0,0,0;False;11;FLOAT3;0,0,0;False;12;FLOAT3;0,0,0;False;14;FLOAT4;0,0,0,0;False;15;FLOAT3;0,0,0;False;0
Version=19202
Node;AmplifyShaderEditor.Vector3Node;1;-274.682,-13.31076;Inherit;False;Property;_Color;Color;0;2;[HDR];[Header];Create;True;1;;0;0;False;2;Header(Test Header);Space(50);False;0,0,0;0,0,0;0;4;FLOAT3;0;FLOAT;1;FLOAT;2;FLOAT;3
Node;AmplifyShaderEditor.RangedFloatNode;2;-482.682,146.6892;Inherit;False;Property;_Float0;Float 0;1;1;[Enum];Create;True;0;1;Option1;0;0;False;1;;False;0;0;0;0;0;1;FLOAT;0
WireConnection;0;0;1;0
Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;3;-8,-15;Float;False;True;-1;2;ASEMaterialInspector;100;5;Hidden;0770190933193b94aaa3065e307002fa;True;Unlit;0;0;Unlit;2;False;True;0;1;False;;0;False;;0;1;False;;0;False;;True;0;False;;0;False;;False;False;False;False;False;False;False;False;False;True;0;False;;False;True;0;False;;False;True;True;True;True;True;0;False;;False;False;False;False;False;False;False;True;False;0;False;;255;False;;255;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;True;1;False;;True;3;False;;True;True;0;False;;0;False;;True;1;RenderType=Opaque=RenderType;True;2;False;0;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;0;;0;0;Standard;1;Vertex Position,InvertActionOnDeselection;1;0;0;1;True;False;;False;0
WireConnection;3;0;1;0
ASEEND*/
//CHKSM=42AC050A646F1BF2270B18EA7D0062D9E386B4B3
//CHKSM=6D95375F618D8B4B492B732E7F0009AB2F1206EE

View File

@ -48,10 +48,13 @@ namespace LWGUI.LwguiGradientEditor
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginChangeCheck();
var gradient = (LwguiGradient)fieldInfo.GetValue(property.serializedObject.targetObject);
LwguiGradientEditorHelper.GradientField(position, label, property, gradient, colorSpace, viewChannelMask, timeRange);
// var lwguiGradient = property.GetLwguiGradientValue();
LwguiGradientEditorHelper.GradientField(position, label, property, colorSpace, viewChannelMask, timeRange);
if (EditorGUI.EndChangeCheck())
{
// property.SetLwguiGradientValue(LwguiGradientWindow.instance.lwguiGradient);
// property.serializedObject.ApplyModifiedProperties();
// EditorUtility.SetDirty(property.serializedObject.targetObject);
}
}
}

View File

@ -17,6 +17,8 @@ namespace LWGUI.LwguiGradientEditor
public Vector4 selectedVectorValue = Vector4.negativeInfinity;
public float selectedFloatValue = float.NegativeInfinity;
public float selectedTime = float.NegativeInfinity;
public float selectedKeysAverageTime = 0;
public uint selectedChannel = 0;
public bool isOnlyColorKeySelected;
public LwguiGradient.LwguiMergedColorCurves mergedCurves;
@ -33,11 +35,15 @@ namespace LWGUI.LwguiGradientEditor
if (curveEditor?.selectedCurves is { Count: > 0 })
{
int selectedKeyCount = 0;
foreach (var curveSelection in curveEditor.selectedCurves.Where(selection => selection != null))
{
var channelID = curveSelection.curveID;
var key = curveEditor.GetKeyframeFromSelection(curveSelection);
selectedAnimationCurves[channelID].AddKey(key);
selectedKeysAverageTime += key.time;
selectedKeyCount++;
selectedChannel |= 1u << channelID;
if (selectedTime != float.NegativeInfinity && selectedTime != key.time)
hasMixedTime = true;
@ -52,10 +58,12 @@ namespace LWGUI.LwguiGradientEditor
selectedFloatValue = key.value;
}
for (int i = 0; i < 4; i++)
selectedKeysAverageTime /= selectedKeyCount;
for (int c = 0; c < (int)LwguiGradient.Channel.Num; c++)
{
if (selectedVectorValue[i] == Vector4.negativeInfinity[i])
selectedVectorValue[i] = 0;
if (selectedVectorValue[c] == Vector4.negativeInfinity[c])
selectedVectorValue[c] = 0;
}
if (selectedFloatValue == float.NegativeInfinity)
@ -72,6 +80,11 @@ namespace LWGUI.LwguiGradientEditor
mergedCurves = new LwguiGradient.LwguiMergedColorCurves();
}
}
public bool HasSelectedChannel(int channelIndex)
{
return (selectedChannel & 1u << channelIndex) != 0;
}
}
#region UI Layout
@ -127,7 +140,7 @@ namespace LWGUI.LwguiGradientEditor
internal ColorSpace colorSpace;
internal LwguiGradient.ChannelMask viewChannelMask;
internal LwguiGradient.GradientTimeRange gradientTimeRange;
private Action<LwguiGradient> _onChange;
private LwguiGradientWindow.ChangeGradientCallback _onChange;
#endregion
@ -242,6 +255,7 @@ namespace LWGUI.LwguiGradientEditor
if (EditorGUI.EndChangeCheck())
{
_changed = true;
EditorGUI.EndEditingActiveTextField();
ApplyGradientChangesToCurve();
}
@ -297,6 +311,10 @@ namespace LWGUI.LwguiGradientEditor
viewChannelMask = (LwguiGradient.ChannelMask)EditorGUI.EnumFlagsField(rect, "Channels", viewChannelMask);
if (EditorGUI.EndChangeCheck())
{
// TODO: Close the pop-up window immediately after modification to avoid inconsistent with the displayed value and the actual value.
// The reason is unknown, the old version does not have this problem.
ReflectionHelper.PopupWindowWithoutFocus_Hide();
_viewSettingschanged = true;
InitGradientEditor(true);
InitCurveEditor(true);
@ -343,11 +361,15 @@ namespace LWGUI.LwguiGradientEditor
rect.width = locationTextWidth + locationWidth;
EditorGUIUtility.labelWidth = locationTextWidth;
EditorGUI.showMixedValue = selectionInfo.hasMixedTime;
EditorGUI.BeginChangeCheck();
var newTime = EditorGUI.FloatField(rect, "Time", selectionInfo.selectedTime * (int)gradientTimeRange) / (int)gradientTimeRange;
// When two keys have the same time, they will be merged, so avoid modifying the time in real time and only apply the changes at the end of the change
var hasChange = EditorGUI.EndChangeCheck();
if (hasChange) _lastEditingTime = newTime;
if (hasChange)
_lastEditingTime = newTime;
if (_lastEditingTime != selectionInfo.selectedTime
&& _lastEditingTime != float.NegativeInfinity
// End editing text
@ -355,10 +377,16 @@ namespace LWGUI.LwguiGradientEditor
// Mouse drag
|| !EditorGUI.IsEditingTextField() && hasChange))
{
_changed = true;
_curveEditor.SetSelectedKeyPositions(Mathf.Clamp01(_lastEditingTime), 0, true, false);
InitGradientEditor(true);
SyncSelectionFromCurveToGradient(true);
var clampedNewTime = Mathf.Clamp01(_lastEditingTime);
var offsetedNewKeyTime = clampedNewTime;
if (HandleNewKeyTimeConflicts(ref offsetedNewKeyTime, clampedNewTime, selectionInfo))
{
_changed = true;
_lastEditingTime = offsetedNewKeyTime;
_curveEditor.SetSelectedKeyPositions(offsetedNewKeyTime, 0, true, false);
InitGradientEditor(true);
SyncSelectionFromCurveToGradient(true);
}
}
}
@ -451,13 +479,93 @@ namespace LWGUI.LwguiGradientEditor
}
}
/// <summary>
/// If the new time of the key is too close to the existing key, Curve Editor will discard one of them.
/// To avoid this, Key conflicts need to be detected and fixed
/// </summary>
private bool HandleNewKeyTimeConflicts(ref float outOffsetedNewKeyTime, float newKeyTime, CurveSelectionInfo selectionInfo)
{
const float MinimumInterval = 0.0001f;
const float NearbyKeyThreshold = MinimumInterval * 10;
// Collect nearby keys
var nearbyKeyTimes = new List<float>();
for (int c = 0; c < _curveEditor.animationCurves.Length; c++)
{
if (!selectionInfo.HasSelectedChannel(c))
continue;
foreach (var key in _curveEditor.animationCurves[c].curve.keys)
{
if (Mathf.Abs(key.time - newKeyTime) < NearbyKeyThreshold
&& !nearbyKeyTimes.Contains(key.time))
nearbyKeyTimes.Add(key.time);
}
}
// Offset New Time to avoid conflicts with existing Keys
if (nearbyKeyTimes.Count > 0)
{
Debug.LogWarning($"LWGUI Gradient Editor: { nearbyKeyTimes.Count } keys that are too close are detected near the new time, " +
$"and LWGUI will automatically fix the conflicts of the times. " +
$"\n But too many nearby keys may still cause some problems, please be careful to use.");
bool isNewTimeOnTheLeft = newKeyTime < selectionInfo.selectedKeysAverageTime;
float offsetDirection = isNewTimeOnTheLeft ? 1 : -1;
nearbyKeyTimes.Sort();
if (!isNewTimeOnTheLeft)
nearbyKeyTimes.Reverse();
for (int i = 0; i < nearbyKeyTimes.Count; i++)
{
var currentNearbyKeyTime = nearbyKeyTimes[i];
if ((newKeyTime - currentNearbyKeyTime) * offsetDirection > MinimumInterval)
continue;
var lastNearbyKeyTime = nearbyKeyTimes[Mathf.Max(0, i - 1)];
// No conflict, no offset required
if (Mathf.Abs(outOffsetedNewKeyTime - currentNearbyKeyTime) >= MinimumInterval
&& Mathf.Abs(outOffsetedNewKeyTime - lastNearbyKeyTime) >= MinimumInterval)
{
break;
}
// Has conflict, offset to the selectedKeysAverageTime
else
{
if (Mathf.Abs(outOffsetedNewKeyTime - lastNearbyKeyTime) < MinimumInterval)
{
outOffsetedNewKeyTime = lastNearbyKeyTime + MinimumInterval * offsetDirection;
}
if (Mathf.Abs(outOffsetedNewKeyTime - currentNearbyKeyTime) < MinimumInterval)
{
outOffsetedNewKeyTime = currentNearbyKeyTime + MinimumInterval * offsetDirection;
}
}
}
var offsetedNewKeyTime = outOffsetedNewKeyTime;
if (nearbyKeyTimes.Any(time => Mathf.Abs(offsetedNewKeyTime - time) < MinimumInterval))
{
EditorUtility.DisplayDialog("LWGUI Gradient Editor",
"Time conflicts of Keys were detected! \nPlease avoid the time when inputting too close to existing Keys!", "OK");
return false;
}
}
return true;
}
private void ShowGradientSwatchArray(Rect rect, List<GradientEditor.Swatch> swatches, LwguiGradient.ChannelMask drawingChannelMask)
{
// GradientEditor.ShowSwatchArray()
ReflectionHelper.GradientEditor_SetStyles();
_isAddGradientKeyFailure = false;
_gradientEditor.ShowSwatchArray(rect, (viewChannelMask & drawingChannelMask) != drawingChannelMask ? new List<GradientEditor.Swatch>() : swatches, drawingChannelMask == LwguiGradient.ChannelMask.Alpha);
_gradientEditor.ShowSwatchArray(rect,
// Swatches are not displayed when ViewChannel != RGB to avoid modifying other channels
(viewChannelMask & drawingChannelMask) != drawingChannelMask ? new List<GradientEditor.Swatch>() : swatches,
drawingChannelMask == LwguiGradient.ChannelMask.Alpha);
// Since the maximum number of Gradient Keys is hard-coded in the engine, keys that exceed the limit can only be displayed and edited in the Curve Editor
if (_isAddGradientKeyFailure)
@ -777,7 +885,12 @@ namespace LWGUI.LwguiGradientEditor
#region Events
public void Init(Rect position, LwguiGradient gradient, ColorSpace colorSpace = ColorSpace.Gamma, LwguiGradient.ChannelMask viewChannelMask = LwguiGradient.ChannelMask.All, LwguiGradient.GradientTimeRange timeRange = LwguiGradient.GradientTimeRange.One, Action<LwguiGradient> onChange = null)
public void Init(Rect position,
LwguiGradient gradient,
ColorSpace colorSpace = ColorSpace.Gamma,
LwguiGradient.ChannelMask viewChannelMask = LwguiGradient.ChannelMask.All,
LwguiGradient.GradientTimeRange timeRange = LwguiGradient.GradientTimeRange.One,
LwguiGradientWindow.ChangeGradientCallback onChange = null)
{
Clear();
@ -817,7 +930,7 @@ namespace LWGUI.LwguiGradientEditor
UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty();
GUI.changed = true;
_onChange?.Invoke(lwguiGradient);
// _onChange?.Invoke(lwguiGradient);
}
if (_viewSettingschanged)

View File

@ -1,6 +1,7 @@
// Copyright (c) Jason Ma
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using LWGUI.Runtime.LwguiGradient;
@ -132,14 +133,15 @@ namespace LWGUI.LwguiGradientEditor
}
/// Lwgui Gradient Field with full Undo/Redo/ContextMenu functions
public static void GradientField(Rect position, GUIContent label, SerializedProperty property, LwguiGradient gradient,
public static void GradientField(Rect position, GUIContent label, SerializedProperty property,
ColorSpace colorSpace = ColorSpace.Gamma,
LwguiGradient.ChannelMask viewChannelMask = LwguiGradient.ChannelMask.All,
LwguiGradient.GradientTimeRange timeRange = LwguiGradient.GradientTimeRange.One)
{
label = EditorGUI.BeginProperty(position, label, property);
EditorGUI.BeginChangeCheck();
var gradient = property.GetLwguiGradientValue();
GradientField(position, label, gradient, colorSpace, viewChannelMask, timeRange,
() => LwguiGradientWindow.RegisterSerializedObjectUndo(property.serializedObject.targetObject));
@ -147,6 +149,8 @@ namespace LWGUI.LwguiGradientEditor
{
GUI.changed = true;
LwguiGradientWindow.RegisterSerializedObjectUndo(property.serializedObject.targetObject);
if (LwguiGradientWindow.instance)
property.SetLwguiGradientValue(LwguiGradientWindow.instance.lwguiGradient);
}
EditorGUI.EndProperty();
}
@ -155,7 +159,8 @@ namespace LWGUI.LwguiGradientEditor
ColorSpace colorSpace = ColorSpace.Gamma,
LwguiGradient.ChannelMask viewChannelMask = LwguiGradient.ChannelMask.All,
LwguiGradient.GradientTimeRange timeRange = LwguiGradient.GradientTimeRange.One,
Func<bool> shouldOpenWindowAfterClickingEvent = null)
Func<bool> shouldOpenWindowAfterClickingEvent = null,
LwguiGradientWindow.ChangeGradientCallback onChange = null)
{
int id = GUIUtility.GetControlID(s_LwguiGradientHash, FocusType.Keyboard, position);
var evt = Event.current;
@ -184,12 +189,36 @@ namespace LWGUI.LwguiGradientEditor
{
s_LwguiGradientID = id;
GUIUtility.keyboardControl = id;
LwguiGradientWindow.Show(gradient, colorSpace, viewChannelMask, timeRange, GUIView.current);
LwguiGradientWindow.Show(gradient, colorSpace, viewChannelMask, timeRange, GUIView.current, onChange);
GUIUtility.ExitGUI();
}
}
return clicked;
}
public static LwguiGradient GetLwguiGradientValue(this SerializedProperty property)
{
LwguiGradient lwguiGradient = new();
var curversProp = property.FindPropertyRelative("_curves");
for (int i = 0; i < curversProp.arraySize; i++)
{
var curveProp = curversProp.GetArrayElementAtIndex(i);
lwguiGradient.rawCurves[i] = curveProp.animationCurveValue;
}
return lwguiGradient;
}
public static void SetLwguiGradientValue(this SerializedProperty property, LwguiGradient lwguiGradient)
{
var curversProp = property.FindPropertyRelative("_curves");
for (int i = 0; i < curversProp.arraySize && i < lwguiGradient.rawCurves.Count; i++)
{
var curveProp = curversProp.GetArrayElementAtIndex(i);
curveProp.animationCurveValue = lwguiGradient.rawCurves[i];
}
}
}
}

View File

@ -32,6 +32,7 @@ namespace LWGUI.LwguiGradientEditor
private static LwguiGradientWindow _lwguiGradientWindow;
public const string presetsEditorPrefID = "LwguiGradient";
public delegate void ChangeGradientCallback(LwguiGradient gradient);
private LwguiGradientEditor _lwguiGradientEditor;
private PresetLibraryLwguiGradientEditor _lwguiGradientLibraryEditor;
@ -43,7 +44,7 @@ namespace LWGUI.LwguiGradientEditor
[NonSerialized] public LwguiGradient.GradientTimeRange gradientTimeRange;
private GUIView _viewToUpdate;
private Action<LwguiGradient> _onChange;
private ChangeGradientCallback _onChange;
#endregion
@ -60,8 +61,8 @@ namespace LWGUI.LwguiGradientEditor
{
get
{
if (!_lwguiGradientWindow)
Debug.LogError("Lwgui Gradient Window not initalized, did you call Show first?");
// if (!_lwguiGradientWindow)
// Debug.LogError("Lwgui Gradient Window not initalized, did you call Show first?");
return _lwguiGradientWindow;
}
}
@ -141,7 +142,7 @@ namespace LWGUI.LwguiGradientEditor
private static LwguiGradientWindow GetWindow(bool focus = true) => (LwguiGradientWindow)GetWindow(typeof(LwguiGradientWindow), true, "LWGUI Gradient Editor", focus);
internal static void Show(LwguiGradient gradient, ColorSpace colorSpace = ColorSpace.Gamma, LwguiGradient.ChannelMask viewChannelMask = LwguiGradient.ChannelMask.All, LwguiGradient.GradientTimeRange timeRange = LwguiGradient.GradientTimeRange.One, GUIView viewToUpdate = null, Action<LwguiGradient> onChange = null)
internal static void Show(LwguiGradient gradient, ColorSpace colorSpace = ColorSpace.Gamma, LwguiGradient.ChannelMask viewChannelMask = LwguiGradient.ChannelMask.All, LwguiGradient.GradientTimeRange timeRange = LwguiGradient.GradientTimeRange.One, GUIView viewToUpdate = null, ChangeGradientCallback onChange = null)
{
if (_lwguiGradientWindow == null)
{
@ -187,8 +188,11 @@ namespace LWGUI.LwguiGradientEditor
public static void RegisterSerializedObjectUndo(Object targetObject)
{
Undo.RegisterCompleteObjectUndo(targetObject, "Lwgui Gradient Editor");
EditorUtility.SetDirty(targetObject);
if (targetObject)
{
Undo.RegisterCompleteObjectUndo(targetObject, "Lwgui Gradient Editor");
EditorUtility.SetDirty(targetObject);
}
}
public static void RegisterRampMapUndo(Object texture, Object assetImporter)
@ -217,15 +221,16 @@ namespace LWGUI.LwguiGradientEditor
{
LwguiGradientHelper.ClearRampPreviewCaches();
UpdatePresetLibraryViewSettings();
SendEvent(true);
SendChangedEvent(true);
}
}
public const string LwguiGradientChangedCommand = "LwguiGradientChanged";
void SendEvent(bool exitGUI)
void SendChangedEvent(bool exitGUI)
{
if (_viewToUpdate != null)
_onChange?.Invoke(lwguiGradient);
if (_viewToUpdate)
{
Event e = EditorGUIUtility.CommandEvent(LwguiGradientChangedCommand);
Repaint();
@ -233,10 +238,6 @@ namespace LWGUI.LwguiGradientEditor
if (exitGUI)
GUIUtility.ExitGUI();
}
if (_onChange != null)
{
_onChange(lwguiGradient);
}
}
private void OnEnable()

View File

@ -2,9 +2,11 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace LWGUI
@ -14,15 +16,14 @@ namespace LWGUI
#region MaterialPropertyHandler
private static readonly Type MaterialPropertyHandler_Type = Assembly.GetAssembly(typeof(Editor)).GetType("UnityEditor.MaterialPropertyHandler");
private static readonly MethodInfo MaterialPropertyHandler_GetHandler_Method = MaterialPropertyHandler_Type.GetMethod("GetHandler", BindingFlags.Static | BindingFlags.NonPublic);
private static readonly PropertyInfo MaterialPropertyHandler_PropertyDrawer_Property = MaterialPropertyHandler_Type.GetProperty("propertyDrawer");
private static readonly FieldInfo MaterialPropertyHandler_DecoratorDrawers_Field = MaterialPropertyHandler_Type.GetField("m_DecoratorDrawers", BindingFlags.NonPublic | BindingFlags.Instance);
public static MaterialPropertyDrawer GetPropertyDrawer(Shader shader, MaterialProperty prop, out List<MaterialPropertyDrawer> decoratorDrawers)
{
decoratorDrawers = new List<MaterialPropertyDrawer>();
var handler = MaterialPropertyHandler_GetHandler_Method.Invoke(null, new object[] { shader, prop.name });
if (handler != null && handler.GetType() == MaterialPropertyHandler_Type)
var handler = MaterialPropertyHandler.GetHandler(shader, prop.name);
if (handler != null)
{
decoratorDrawers = MaterialPropertyHandler_DecoratorDrawers_Field.GetValue(handler) as List<MaterialPropertyDrawer>;
return MaterialPropertyHandler_PropertyDrawer_Property.GetValue(handler, null) as MaterialPropertyDrawer;
@ -36,11 +37,22 @@ namespace LWGUI
return GetPropertyDrawer(shader, prop, out _);
}
public static void InvalidatePropertyCache(Shader shader)
{
MaterialPropertyHandler.InvalidatePropertyCache(shader);
}
#endregion
#region MaterialEditor
private static readonly Type MaterialEditor_Type = typeof(MaterialEditor);
private static readonly PropertyInfo MaterialEditor_RendererForAnimationMode_Property = MaterialEditor_Type.GetProperty("rendererForAnimationMode", BindingFlags.NonPublic | BindingFlags.Instance);
private static readonly MethodInfo MaterialEditor_TexturePropertyBody_Method = MaterialEditor_Type.GetMethod("TexturePropertyBody", BindingFlags.NonPublic | BindingFlags.Instance);
public static float DoPowerRangeProperty(Rect position, MaterialProperty prop, GUIContent label, float power)
{
return MaterialEditor.DoPowerRangeProperty(position, prop, label, power);
@ -62,17 +74,25 @@ namespace LWGUI
GameObject gameObject = property.tracker.activeEditors[0].target as GameObject;
if (gameObject)
{
outRenderers.AddRange(gameObject.GetComponents<MeshRenderer>());
outRenderers.AddRange(gameObject.GetComponents<SkinnedMeshRenderer>());
outRenderers.AddRange(gameObject.GetComponents<Renderer>());
}
}
return outRenderers;
}
public static Renderer GetRendererForAnimationMode(this MaterialEditor materialEditor)
{
return MaterialEditor_RendererForAnimationMode_Property.GetValue(materialEditor, null) as Renderer;
}
public static Texture TexturePropertyBody(this MaterialEditor materialEditor, Rect position, MaterialProperty prop)
{
return MaterialEditor_TexturePropertyBody_Method.Invoke(materialEditor, new object[] { position, prop }) as Texture;
}
#endregion
#region EditorUtility
public static void DisplayCustomMenuWithSeparators(Rect position, string[] options, bool[] enabled, bool[] separator, int[] selected, EditorUtility.SelectMenuItemFunction callback, object userData = null, bool showHotkey = false)
@ -82,20 +102,18 @@ namespace LWGUI
#endregion
#region EditorGUI
public static float EditorGUI_Indent => EditorGUI.indentLevel;
#endregion
#region EditorGUILayout
public static float EditorGUILayout_kLabelFloatMinW => EditorGUILayout.kLabelFloatMinW;
#endregion
#region MaterialEnumDrawer
// UnityEditor.MaterialEnumDrawer(string enumName)
@ -126,8 +144,7 @@ namespace LWGUI
}
#endregion
#region MaterialProperty.PropertyData
#if UNITY_2022_1_OR_NEWER
@ -153,6 +170,15 @@ namespace LWGUI
#endregion
#region Animation
public static bool MaterialAnimationUtility_OverridePropertyColor(MaterialProperty materialProp, Renderer target, out Color color)
{
return MaterialAnimationUtility.OverridePropertyColor(materialProp, target, out color);
}
#endregion
#region GUI
private static readonly MethodInfo gui_Button_Method = typeof(GUI).GetMethod("Button", BindingFlags.Static | BindingFlags.NonPublic);
@ -220,6 +246,11 @@ namespace LWGUI
return (float)GetTime_Method.Invoke(gradientEditor, new object[] { actualTime });
}
public static void PopupWindowWithoutFocus_Hide()
{
PopupWindowWithoutFocus.Hide();
}
#endregion
#region CurveEditor

View File

@ -53,5 +53,39 @@ namespace LWGUI
#endregion
#region MaterialProperty
public static float GetNumericValue(this MaterialProperty prop)
{
switch (prop.type)
{
case MaterialProperty.PropType.Float or MaterialProperty.PropType.Range:
return prop.floatValue;
case MaterialProperty.PropType.Int:
return prop.intValue;
default:
Debug.LogError($"LWGUI: Material Property { prop.name } is NOT numeric type.");
return 0;
}
}
public static void SetNumericValue(this MaterialProperty prop, float value)
{
switch (prop.type)
{
case MaterialProperty.PropType.Float or MaterialProperty.PropType.Range:
prop.floatValue = value;
break;
case MaterialProperty.PropType.Int:
prop.intValue = (int)value;
break;
default:
Debug.LogError($"LWGUI: Material Property { prop.name } is NOT numeric type.");
break;
}
}
#endregion
}
}

Binary file not shown.

View File

@ -17,281 +17,342 @@ MonoBehaviour:
propertyValues: []
enabledKeywords: []
disabledKeywords: []
enabledPasses: []
disabledPasses: []
renderQueue: -1
- presetName: Rim
propertyValues:
- propertyName: _MatCapAdditiveMap
propertyType: 4
floatValue: 0
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 2800000, guid: 6fb1633902b561046bd6b453be19d3d4, type: 3}
- propertyName: _MatCapAdditiveUvScale
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
- propertyName: _MatCapAdditiveExtractBrightArea
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
enabledKeywords: []
disabledKeywords: []
enabledPasses: []
disabledPasses: []
renderQueue: -1
- presetName: RimSoft
propertyValues:
- propertyName: _MatCapAdditiveMap
propertyType: 4
floatValue: 0
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 2800000, guid: 6c56dbbd85e89c3409f7d4d9e868fd03, type: 3}
- propertyName: _MatCapAdditiveUvScale
propertyType: 3
floatValue: 1
floatValue: 0.99
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
- propertyName: _MatCapAdditiveExtractBrightArea
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
enabledKeywords: []
disabledKeywords: []
enabledPasses: []
disabledPasses: []
renderQueue: -1
- presetName: Glossy01
propertyValues:
- propertyName: _MatCapAdditiveMap
propertyType: 4
floatValue: 0
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 2800000, guid: 222a81aa69e4db943af2f3c9f8bb2851, type: 3}
- propertyName: _MatCapAdditiveUvScale
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
- propertyName: _MatCapAdditiveExtractBrightArea
propertyType: 3
floatValue: 0
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
enabledKeywords: []
disabledKeywords: []
enabledPasses: []
disabledPasses: []
renderQueue: -1
- presetName: Glossy01(HighLight only - 1)
propertyValues:
- propertyName: _MatCapAdditiveMap
propertyType: 4
floatValue: 0
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 2800000, guid: 222a81aa69e4db943af2f3c9f8bb2851, type: 3}
- propertyName: _MatCapAdditiveUvScale
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
- propertyName: _MatCapAdditiveExtractBrightArea
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
enabledKeywords: []
disabledKeywords: []
enabledPasses: []
disabledPasses: []
renderQueue: -1
- presetName: Glossy01(HighLight only - 2)
propertyValues:
- propertyName: _MatCapAdditiveMap
propertyType: 4
floatValue: 0
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 2800000, guid: 222a81aa69e4db943af2f3c9f8bb2851, type: 3}
- propertyName: _MatCapAdditiveUvScale
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
- propertyName: _MatCapAdditiveExtractBrightArea
propertyType: 3
floatValue: 2
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
enabledKeywords: []
disabledKeywords: []
enabledPasses: []
disabledPasses: []
renderQueue: -1
- presetName: Glossy01(HighLight only - 3)
propertyValues:
- propertyName: _MatCapAdditiveMap
propertyType: 4
floatValue: 0
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 2800000, guid: 222a81aa69e4db943af2f3c9f8bb2851, type: 3}
- propertyName: _MatCapAdditiveUvScale
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
- propertyName: _MatCapAdditiveExtractBrightArea
propertyType: 3
floatValue: 3
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
enabledKeywords: []
disabledKeywords: []
enabledPasses: []
disabledPasses: []
renderQueue: -1
- presetName: BlackSmoothSpecular01
propertyValues:
- propertyName: _MatCapAdditiveMap
propertyType: 4
floatValue: 0
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 2800000, guid: 16ed4056d7dcd804a812c96b7ffd83b5, type: 3}
- propertyName: _MatCapAdditiveUvScale
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
- propertyName: _MatCapAdditiveExtractBrightArea
propertyType: 3
floatValue: 0
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
enabledKeywords: []
disabledKeywords: []
enabledPasses: []
disabledPasses: []
renderQueue: -1
- presetName: Rainbow
propertyValues:
- propertyName: _MatCapAdditiveMap
propertyType: 4
floatValue: 0
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 2800000, guid: e3e710d0df43e6e4aba1b11e50ffb72c, type: 3}
- propertyName: _MatCapAdditiveUvScale
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
- propertyName: _MatCapAdditiveExtractBrightArea
propertyType: 3
floatValue: 0
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
- propertyName: _MatCapAdditiveIntensity
propertyType: 3
floatValue: 0.25
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
enabledKeywords: []
disabledKeywords: []
enabledPasses: []
disabledPasses: []
renderQueue: -1
- presetName: TwoLights(Soft)
propertyValues:
- propertyName: _MatCapAdditiveMap
propertyType: 4
floatValue: 0
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 2800000, guid: 149918de7435b174ba49e352b476b24a, type: 3}
- propertyName: _MatCapAdditiveUvScale
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
- propertyName: _MatCapAdditiveExtractBrightArea
propertyType: 3
floatValue: 0
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
- propertyName: _MatCapAdditiveIntensity
propertyType: 3
floatValue: 0.375
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
enabledKeywords: []
disabledKeywords: []
enabledPasses: []
disabledPasses: []
renderQueue: -1
- presetName: TwoLights(HighLight only)
propertyValues:
- propertyName: _MatCapAdditiveMap
propertyType: 4
floatValue: 0
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 2800000, guid: 149918de7435b174ba49e352b476b24a, type: 3}
- propertyName: _MatCapAdditiveUvScale
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
- propertyName: _MatCapAdditiveExtractBrightArea
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
- propertyName: _MatCapAdditiveIntensity
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
enabledKeywords: []
disabledKeywords: []
enabledPasses: []
disabledPasses: []
renderQueue: -1
- presetName: RimHard(LightFromTop)
propertyValues:
- propertyName: _MatCapAdditiveMap
propertyType: 4
floatValue: 0
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 2800000, guid: fc7cd5560458f944baff8815e36c178e, type: 3}
- propertyName: _MatCapAdditiveUvScale
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
- propertyName: _MatCapAdditiveExtractBrightArea
propertyType: 3
floatValue: 1
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
- propertyName: _MatCapAdditiveIntensity
propertyType: 3
floatValue: 0.5
intValue: 0
colorValue: {r: 0, g: 0, b: 0, a: 0}
vectorValue: {x: 0, y: 0, z: 0, w: 0}
textureValue: {fileID: 0}
enabledKeywords: []
disabledKeywords: []
enabledPasses: []
disabledPasses: []
renderQueue: -1