场景设计
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3efbebad5114aa4eae3f9b1dbdae53d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,195 @@
|
||||
//--------------------------------------------------------------------------//
|
||||
// Copyright 2023-2025 Chocolate Dinosaur Ltd. All rights reserved. //
|
||||
// For full documentation visit https://www.chocolatedinosaur.com //
|
||||
//--------------------------------------------------------------------------//
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace ChocDino.UIFX.Editor
|
||||
{
|
||||
internal struct AboutButton
|
||||
{
|
||||
public GUIContent title;
|
||||
public string url;
|
||||
|
||||
public AboutButton(string title, string url)
|
||||
{
|
||||
this.title = new GUIContent(title);
|
||||
this.url = url;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct AboutSection
|
||||
{
|
||||
public GUIContent title;
|
||||
public AboutButton[] buttons;
|
||||
|
||||
public AboutSection(string title)
|
||||
{
|
||||
this.title = new GUIContent(title);
|
||||
this.buttons = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal class AboutToolbar
|
||||
{
|
||||
private int _selectedIndex = -1;
|
||||
private AboutInfo[] _infos;
|
||||
|
||||
public AboutToolbar(AboutInfo[] infos)
|
||||
{
|
||||
_infos = infos;
|
||||
}
|
||||
|
||||
internal void OnGUI()
|
||||
{
|
||||
if (!Preferences.ShowHeaderAboutButtons)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
for (int i = 0; i < _infos.Length; i++)
|
||||
{
|
||||
if (_infos[i].Visible())
|
||||
{
|
||||
if (_infos[i].OnHeaderGUI())
|
||||
{
|
||||
if (i != _selectedIndex)
|
||||
{
|
||||
if (_selectedIndex >= 0)
|
||||
{
|
||||
_infos[_selectedIndex].isExpanded = false;
|
||||
}
|
||||
_selectedIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
if (_selectedIndex >= 0)
|
||||
{
|
||||
_infos[_selectedIndex].OnGUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A customisable UI window that displays basic information about the asset/component and has
|
||||
/// categories of buttons that link to documentation and support
|
||||
/// </summary>
|
||||
internal class AboutInfo
|
||||
{
|
||||
private string iconPath;
|
||||
private GUIContent title;
|
||||
internal AboutSection[] sections;
|
||||
private GUIContent icon;
|
||||
private GUIContent buttonLabelOpen;
|
||||
private GUIContent buttonLabelClosed;
|
||||
private System.Predicate<bool> showAction;
|
||||
|
||||
internal bool isExpanded = false;
|
||||
private static GUIStyle paddedBoxStyle;
|
||||
private static GUIStyle richBoldLabelStyle;
|
||||
private static GUIStyle richButtonStyle;
|
||||
private static GUIStyle titleStyle;
|
||||
|
||||
public AboutInfo(string buttonLabel, string title, string iconPath, System.Predicate<bool> showAction = null)
|
||||
{
|
||||
this.title = new GUIContent(title);
|
||||
this.iconPath = iconPath;
|
||||
this.buttonLabelOpen = new GUIContent("▼ " + buttonLabel);
|
||||
this.buttonLabelClosed = new GUIContent("► " + buttonLabel);
|
||||
this.showAction = showAction;
|
||||
sections = null;
|
||||
}
|
||||
|
||||
internal bool Visible()
|
||||
{
|
||||
if (this.showAction != null)
|
||||
{
|
||||
return showAction.Invoke(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
internal bool OnHeaderGUI()
|
||||
{
|
||||
isExpanded = GUILayout.Toggle(isExpanded, isExpanded?this.buttonLabelOpen:this.buttonLabelClosed, GUI.skin.button);
|
||||
return isExpanded;
|
||||
}
|
||||
|
||||
internal void OnGUI()
|
||||
{
|
||||
if (paddedBoxStyle == null)
|
||||
{
|
||||
paddedBoxStyle = new GUIStyle(GUI.skin.window);
|
||||
paddedBoxStyle.padding = new RectOffset(8, 8, 16, 16);
|
||||
}
|
||||
if (titleStyle == null)
|
||||
{
|
||||
titleStyle = new GUIStyle(EditorStyles.largeLabel);
|
||||
titleStyle.wordWrap = true;
|
||||
titleStyle.richText = true;
|
||||
titleStyle.alignment = TextAnchor.UpperCenter;
|
||||
}
|
||||
if (richBoldLabelStyle == null)
|
||||
{
|
||||
richBoldLabelStyle = new GUIStyle(EditorStyles.boldLabel);
|
||||
richBoldLabelStyle.richText = true;
|
||||
richBoldLabelStyle.alignment = TextAnchor.UpperCenter;
|
||||
richBoldLabelStyle.margin.top = 20;
|
||||
richBoldLabelStyle.margin.bottom = 10;
|
||||
richBoldLabelStyle.wordWrap = true;
|
||||
richBoldLabelStyle.fontSize = 14;
|
||||
}
|
||||
if (richButtonStyle == null)
|
||||
{
|
||||
richButtonStyle = new GUIStyle(GUI.skin.button);
|
||||
richButtonStyle.richText = true;
|
||||
richButtonStyle.stretchWidth = true;
|
||||
}
|
||||
|
||||
if (this.icon == null)
|
||||
{
|
||||
this.icon = new GUIContent(Resources.Load<Texture2D>(this.iconPath));
|
||||
}
|
||||
|
||||
if (isExpanded)
|
||||
{
|
||||
GUILayout.BeginVertical(paddedBoxStyle);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Label(this.icon);
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Label(this.title, titleStyle);
|
||||
|
||||
foreach (AboutSection section in this.sections)
|
||||
{
|
||||
GUILayout.Label(section.title, richBoldLabelStyle);
|
||||
GUILayout.BeginVertical();
|
||||
if (section.buttons != null)
|
||||
{
|
||||
foreach (AboutButton button in section.buttons)
|
||||
{
|
||||
if (GUILayout.Button(button.title, richButtonStyle))
|
||||
{
|
||||
Application.OpenURL(button.url);
|
||||
}
|
||||
}
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c21bdd0f568f3e74cbf56ac6d3add39b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 274847
|
||||
packageName: UIFX - Glow Filter
|
||||
packageVersion: 1.9.10
|
||||
assetPath: Assets/ChocDino/UIFX/Editor/Scripts/Common/AboutInfo.cs
|
||||
uploadId: 833966
|
||||
@@ -0,0 +1,242 @@
|
||||
//--------------------------------------------------------------------------//
|
||||
// Copyright 2023-2025 Chocolate Dinosaur Ltd. All rights reserved. //
|
||||
// For full documentation visit https://www.chocolatedinosaur.com //
|
||||
//--------------------------------------------------------------------------//
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace ChocDino.UIFX.Editor
|
||||
{
|
||||
public class BaseEditor : UnityEditor.Editor
|
||||
{
|
||||
protected const string s_aboutHelp = "About & Help";
|
||||
|
||||
protected static readonly string DiscordUrl = "https://discord.gg/wKRzKAHVUE";
|
||||
protected static readonly string ForumBundleUrl = "https://discussions.unity.com/t/released-uifx-bundle-advanced-effects-for-unity-ui/940575";
|
||||
protected static readonly string GithubUrl = "https://github.com/Chocolate-Dinosaur/UIFX/issues";
|
||||
protected static readonly string SupportEmailUrl = "mailto:support@chocdino.com";
|
||||
protected static readonly string UIFXBundleWebsiteUrl = "https://www.chocdino.com/products/uifx/bundle/about/";
|
||||
protected static readonly string AssetStoreBundleUrl = "https://assetstore.unity.com/packages/slug/266945?aid=1100lSvNe";
|
||||
protected static readonly string AssetStoreBundleReviewUrl = "https://assetstore.unity.com/packages/slug/266945?aid=1100lSvNe#reviews";
|
||||
|
||||
internal static readonly AboutInfo s_upgradeToBundle =
|
||||
new AboutInfo("Upgrade ★", "This asset is part of the <b>UIFX Bundle</b> asset.\r\n\r\nAs an existing customer you are entitled to a discounted upgrade!", "uifx-logo-bundle", BaseEditor.ShowUpgradeBundleButton)
|
||||
{
|
||||
sections = new AboutSection[]
|
||||
{
|
||||
new AboutSection("Upgrade")
|
||||
{
|
||||
buttons = new AboutButton[]
|
||||
{
|
||||
new AboutButton("<color=#ffd700>★ </color>Upgrade to UIFX Bundle<color=#ffd700> ★</color>", AssetStoreBundleUrl),
|
||||
}
|
||||
},
|
||||
new AboutSection("Read More")
|
||||
{
|
||||
buttons = new AboutButton[]
|
||||
{
|
||||
new AboutButton("About UIFX Bundle", UIFXBundleWebsiteUrl),
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
internal static bool ShowUpgradeBundleButton(bool dummy)
|
||||
{
|
||||
return !DetectUIFXBundle();
|
||||
}
|
||||
|
||||
internal static bool DetectUIFXBundle()
|
||||
{
|
||||
// This GUID is from FillGradientFilterEditor.cs.meta which is currently only included in the UIFX Bundle.
|
||||
const string fileGUID = "df03afa3ecd8c6941a0462c7c870ae83";
|
||||
return !string.IsNullOrEmpty(AssetDatabase.GUIDToAssetPath(fileGUID));
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// Creates a button that toggles between two texts but maintains the same size by using the size of the largest.
|
||||
// This is useful so that the button doesn't change size resulting in the mouse cursor no longer being over the button.
|
||||
// </summary>
|
||||
protected bool ToggleButton(bool value, GUIContent labelTrue, GUIContent labelFalse)
|
||||
{
|
||||
float maxWidth = Mathf.Max(GUI.skin.button.CalcSize(labelTrue).x, GUI.skin.button.CalcSize(labelFalse).x);
|
||||
GUIContent content = value ? labelTrue : labelFalse;
|
||||
return GUILayout.Button(content, GUILayout.Width(maxWidth));
|
||||
}
|
||||
|
||||
protected void EnumAsToolbarCompact(SerializedProperty prop, GUIContent displayName = null)
|
||||
{
|
||||
if (displayName == null)
|
||||
{
|
||||
displayName = new GUIContent(prop.displayName);
|
||||
}
|
||||
|
||||
if (prop.hasMultipleDifferentValues)
|
||||
{
|
||||
EditorGUILayout.PropertyField(prop, displayName);
|
||||
return;
|
||||
}
|
||||
|
||||
Rect rect = EditorGUILayout.GetControlRect();
|
||||
EditorGUI.BeginProperty(rect, displayName, prop);
|
||||
|
||||
EditorGUI.PrefixLabel(rect, displayName);
|
||||
rect.xMin += EditorGUIUtility.labelWidth;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
int newIndex = prop.enumValueIndex;
|
||||
newIndex = GUI.Toolbar(rect, newIndex, prop.enumDisplayNames);
|
||||
|
||||
// Only assign the value back if it was actually changed by the user.
|
||||
// Otherwise a single value will be assigned to all objects when multi-object editing,
|
||||
// even when the user didn't touch the control.
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
prop.enumValueIndex = newIndex;
|
||||
}
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
|
||||
protected void EnumAsToolbar(SerializedProperty prop, GUIContent displayName = null)
|
||||
{
|
||||
if (displayName == null)
|
||||
{
|
||||
displayName = new GUIContent(prop.displayName);
|
||||
}
|
||||
|
||||
if (prop.hasMultipleDifferentValues)
|
||||
{
|
||||
EditorGUILayout.PropertyField(prop, displayName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EditorGUIUtility.wideMode)
|
||||
{
|
||||
EditorGUILayout.PropertyField(prop, displayName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rect rect = EditorGUILayout.GetControlRect(true);
|
||||
EditorGUI.BeginProperty(rect, displayName, prop);
|
||||
|
||||
EditorGUI.PrefixLabel(rect, displayName);
|
||||
rect.xMin += EditorGUIUtility.labelWidth;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
int newIndex = GUI.Toolbar(rect, prop.enumValueIndex, prop.enumDisplayNames);
|
||||
|
||||
// Only assign the value back if it was actually changed by the user.
|
||||
// Otherwise a single value will be assigned to all objects when multi-object editing,
|
||||
// even when the user didn't touch the control.
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
prop.enumValueIndex = newIndex;
|
||||
}
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
}
|
||||
|
||||
protected void TextureScaleOffset(SerializedProperty propTexture, SerializedProperty propScale, SerializedProperty propOffset, GUIContent displayName)
|
||||
{
|
||||
EditorGUILayout.PropertyField(propTexture);
|
||||
//EditorGUILayout.PropertyField(_propTextureOffset, Content_Offset);
|
||||
//EditorGUILayout.PropertyField(_propTextureScale, Content_Scale);
|
||||
|
||||
Rect rect = EditorGUILayout.GetControlRect(true, 2 * (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing), EditorStyles.layerMaskField);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
Vector4 scaleOffset = new Vector4(propScale.vector2Value.x, propScale.vector2Value.y, propOffset.vector2Value.x, propOffset.vector2Value.y);
|
||||
EditorGUI.indentLevel++;
|
||||
scaleOffset = MaterialEditor.TextureScaleOffsetProperty(rect, scaleOffset, false);
|
||||
EditorGUI.indentLevel--;
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
propScale.vector2Value = new Vector2(scaleOffset.x, scaleOffset.y);
|
||||
propOffset.vector2Value = new Vector2(scaleOffset.z, scaleOffset.w);
|
||||
}
|
||||
}
|
||||
|
||||
protected SerializedProperty VerifyFindProperty(string propertyPath)
|
||||
{
|
||||
SerializedProperty result = serializedObject.FindProperty(propertyPath);
|
||||
Debug.Assert(result != null);
|
||||
if (result == null)
|
||||
{
|
||||
Debug.LogError("Failed to find property '" + propertyPath + "' in object '" + serializedObject.ToString()+ "'");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static SerializedProperty VerifyFindPropertyRelative(SerializedProperty property, string relativePropertyPath)
|
||||
{
|
||||
SerializedProperty result = null;
|
||||
Debug.Assert(property != null);
|
||||
if (property == null)
|
||||
{
|
||||
Debug.LogError("Property is null while finding relative property '"+ relativePropertyPath + "'");
|
||||
}
|
||||
else
|
||||
{
|
||||
result = property.FindPropertyRelative(relativePropertyPath);
|
||||
Debug.Assert(result != null);
|
||||
if (result == null)
|
||||
{
|
||||
Debug.LogError("Failed to find relative property '" + relativePropertyPath + "' in property '" + property.name + "'");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#if false
|
||||
void ShowAlignmentSelector()
|
||||
{
|
||||
GUILayoutOption layout = GUILayout.ExpandWidth(false);
|
||||
GUIStyle style = UnityEditor.EditorStyles.toolbarButton;
|
||||
//style.margin = new RectOffset(0, 0, 0, 0);
|
||||
//style.border = new RectOffset(0, 0, 0, 0);
|
||||
|
||||
bool toggle;
|
||||
GUILayout.BeginVertical();
|
||||
GUILayout.BeginHorizontal();
|
||||
toggle = _propGradientCenterX.floatValue == -1f;
|
||||
toggle = GUILayout.Toggle(toggle, "┏", style, layout);
|
||||
GUILayout.Toggle(false, "┳", style, layout);
|
||||
GUILayout.Toggle(false, "┓", style, layout);
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Toggle(false, "┣", style, layout);
|
||||
GUILayout.Toggle(false, "╋", style, layout);
|
||||
GUILayout.Toggle(false, "┫", style, layout);
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Toggle(false, "┗", style, layout);
|
||||
GUILayout.Toggle(false, "┻", style, layout);
|
||||
GUILayout.Toggle(false, "┛", style, layout);
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
#endif
|
||||
|
||||
internal static Gradient GetGradient(SerializedProperty gradientProperty)
|
||||
{
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
return gradientProperty.gradientValue;
|
||||
#else
|
||||
System.Reflection.PropertyInfo propertyInfo = typeof(SerializedProperty).GetProperty("gradientValue", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
if (propertyInfo == null) { return null; }
|
||||
else { return propertyInfo.GetValue(gradientProperty, null) as Gradient; }
|
||||
#endif
|
||||
}
|
||||
internal static void SetGradient(SerializedProperty gradientProperty, Gradient value)
|
||||
{
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
gradientProperty.gradientValue = value;
|
||||
#else
|
||||
System.Reflection.PropertyInfo propertyInfo = typeof(SerializedProperty).GetProperty("gradientValue", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
if (propertyInfo != null) { propertyInfo.SetValue(gradientProperty, value); }
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c1fb9a5a2bdb55b449705cc16d67f6dd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 274847
|
||||
packageName: UIFX - Glow Filter
|
||||
packageVersion: 1.9.10
|
||||
assetPath: Assets/ChocDino/UIFX/Editor/Scripts/Common/BaseEditor.cs
|
||||
uploadId: 833966
|
||||
@@ -0,0 +1,294 @@
|
||||
//--------------------------------------------------------------------------//
|
||||
// Copyright 2023-2025 Chocolate Dinosaur Ltd. All rights reserved. //
|
||||
// For full documentation visit https://www.chocolatedinosaur.com //
|
||||
//--------------------------------------------------------------------------//
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace ChocDino.UIFX.Editor
|
||||
{
|
||||
internal static class Preferences
|
||||
{
|
||||
internal static readonly string SettingsPath = "Project/Chocolate Dinosaur/UIFX";
|
||||
|
||||
private const string KeyPrefix = "UIFX.";
|
||||
|
||||
private const string BakedImageSubfolderKey = KeyPrefix + "BakedImageSubfolder";
|
||||
private const string ShowHeaderAboutButtonsKey = KeyPrefix + "ShowHeaderAboutButtons";
|
||||
private const string ShowFooterBakeButtonsKey = KeyPrefix + "ShowFooterBakeButtons";
|
||||
private const string CameraSourcePreviewExpandKey = KeyPrefix + "CameraSource.PreviewExpanded";
|
||||
|
||||
internal const string DefaultBakedImageAssetsSubfolder = "Baked-Images";
|
||||
|
||||
internal static string BakedImageSubfolder
|
||||
{
|
||||
get { return EditorPrefs.GetString(BakedImageSubfolderKey, DefaultBakedImageAssetsSubfolder); }
|
||||
set { EditorPrefs.SetString(BakedImageSubfolderKey, value); }
|
||||
}
|
||||
|
||||
internal static bool ShowHeaderAboutButtons
|
||||
{
|
||||
get { return EditorPrefs.GetBool(ShowHeaderAboutButtonsKey, true); }
|
||||
set { EditorPrefs.SetBool(ShowHeaderAboutButtonsKey, value); }
|
||||
}
|
||||
|
||||
internal static bool ShowFooterBakeButtons
|
||||
{
|
||||
get { return EditorPrefs.GetBool(ShowFooterBakeButtonsKey, true); }
|
||||
set { EditorPrefs.SetBool(ShowFooterBakeButtonsKey, value); }
|
||||
}
|
||||
|
||||
internal static bool CameraSourcePreviewExpand
|
||||
{
|
||||
get { return EditorPrefs.GetBool(CameraSourcePreviewExpandKey, true); }
|
||||
set { EditorPrefs.SetBool(CameraSourcePreviewExpandKey, value); }
|
||||
}
|
||||
|
||||
|
||||
[SettingsProvider]
|
||||
static SettingsProvider CreateSettingsProvider()
|
||||
{
|
||||
return new UIFXSettingsProvider(SettingsPath, SettingsScope.Project);
|
||||
}
|
||||
|
||||
private class UIFXSettingsProvider : SettingsProvider
|
||||
{
|
||||
public UIFXSettingsProvider(string path, SettingsScope scope) : base(path, scope)
|
||||
{
|
||||
this.keywords = new HashSet<string>(new[] { "UIFX", "Chocolate", "Dinosaur", "ChocDino", "UI", "GUI", "UGUI" });
|
||||
}
|
||||
|
||||
private static readonly GUIContent Content_BakedImagesFolder = new GUIContent("Baked Images Folder", "Folder path for baked images. Path is relative to Assets folder.");
|
||||
private static readonly GUIContent Content_ShowHeaderAboutButtons = new GUIContent("Show Header About Buttons", "Show the about/help buttons that appear at the top of each UIFX component.");
|
||||
private static readonly GUIContent Content_ShowFooterBakeButtons = new GUIContent("Show Footer Bake Buttons", "Show the bake/save PNG buttons that appear at the bottom of each UIFX component.");
|
||||
|
||||
private string _defines;
|
||||
private string _oldDefines;
|
||||
private bool _unappliedChanges;
|
||||
private BuildTargetGroup _buildTarget;
|
||||
|
||||
public override void OnActivate(string searchContext, VisualElement rootElement)
|
||||
{
|
||||
_buildTarget = BuildTargetGroup.Unknown;
|
||||
}
|
||||
|
||||
public override void OnDeactivate()
|
||||
{
|
||||
}
|
||||
|
||||
private void CacheDefines()
|
||||
{
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
var namedBuildTarget = UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(_buildTarget);
|
||||
_oldDefines = _defines = PlayerSettings.GetScriptingDefineSymbols(namedBuildTarget);
|
||||
#else
|
||||
_oldDefines = _defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(_buildTarget);
|
||||
#endif
|
||||
}
|
||||
|
||||
private void ApplyDefines()
|
||||
{
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
var namedBuildTarget = UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(_buildTarget);
|
||||
PlayerSettings.SetScriptingDefineSymbols(namedBuildTarget, _defines);
|
||||
#else
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(_buildTarget, _defines);
|
||||
#endif
|
||||
CacheDefines();
|
||||
}
|
||||
|
||||
private bool HasDefine(string define)
|
||||
{
|
||||
return (_defines.IndexOf(define) >= 0);
|
||||
}
|
||||
|
||||
private void AddDefine(string define)
|
||||
{
|
||||
_defines = (_defines + ";" + define + ";").Replace(";;", ";");
|
||||
}
|
||||
|
||||
private void RemoveDefine(string define)
|
||||
{
|
||||
_defines = _defines.Replace(define, "").Replace(";;", ";");
|
||||
}
|
||||
|
||||
private bool HasDefineChanged(string define)
|
||||
{
|
||||
bool a = HasDefine(define);
|
||||
bool b = (_oldDefines.IndexOf(define) >= 0);
|
||||
return (a != b);
|
||||
}
|
||||
|
||||
public override void OnTitleBarGUI()
|
||||
{
|
||||
if (_unappliedChanges)
|
||||
{
|
||||
GUI.color = Color.green;
|
||||
if (GUILayout.Button("Apply Changes"))
|
||||
{
|
||||
ApplyDefines();
|
||||
}
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnFooterBarGUI()
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnGUI(string searchContext)
|
||||
{
|
||||
const string UIFX_SUPPORT_TEXT_ANIMATOR = "UIFX_SUPPORT_TEXT_ANIMATOR";
|
||||
const string UIFX_BETA = "UIFX_BETA";
|
||||
const string UIFX_UNRELEASED = "UIFX_UNRELEASED";
|
||||
const string UIFX_FILTER_HIDE_INSPECTOR_PREVIEW = "UIFX_FILTER_HIDE_INSPECTOR_PREVIEW";
|
||||
const string UIFX_LOG = "UIFX_LOG";
|
||||
const string UIFX_FILTER_DEBUG = "UIFX_FILTER_DEBUG";
|
||||
const string UIFX_FILTERS_FORCE_UPDATE_PLAYMODE = "UIFX_FILTERS_FORCE_UPDATE_PLAYMODE";
|
||||
const string UIFX_FILTERS_FORCE_UPDATE_EDITMODE = "UIFX_FILTERS_FORCE_UPDATE_EDITMODE";
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
ShowEditorPref(Content_BakedImagesFolder, BakedImageSubfolderKey, DefaultBakedImageAssetsSubfolder);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
ShowEditorPref(Content_ShowHeaderAboutButtons, ShowHeaderAboutButtonsKey, true);
|
||||
ShowEditorPref(Content_ShowFooterBakeButtons, ShowFooterBakeButtonsKey, true);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
GUILayout.Label("Active platform is: " + BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget).ToString());
|
||||
|
||||
bool isActivePlatform = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget) == _buildTarget;
|
||||
|
||||
bool changes = false;
|
||||
{
|
||||
if (isActivePlatform)
|
||||
{
|
||||
GUI.color = new Color(1.1f, 1.1f, 1.1f, 1f);
|
||||
}
|
||||
BuildTargetGroup group = EditorGUILayout.BeginBuildTargetSelectionGrouping();
|
||||
if (_buildTarget != group)
|
||||
{
|
||||
_buildTarget = group;
|
||||
CacheDefines();
|
||||
}
|
||||
changes |= ShowDefineToggle("Text Animator Support (Requires Febucci.TextAnimator package)", UIFX_SUPPORT_TEXT_ANIMATOR);
|
||||
changes |= ShowDefineToggle("Hide Inspector Filter Preview", UIFX_FILTER_HIDE_INSPECTOR_PREVIEW);
|
||||
changes |= ShowDefineToggle("Beta Features", UIFX_BETA);
|
||||
EditorGUILayout.EndBuildTargetSelectionGrouping();
|
||||
}
|
||||
GUI.color = Color.white;
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
|
||||
|
||||
if (SystemInfo.deviceName == "DESKTOP-ULTRA")
|
||||
{
|
||||
GUILayout.Label("Developer Mode:", EditorStyles.largeLabel);
|
||||
if (isActivePlatform)
|
||||
{
|
||||
GUI.color = new Color(1.1f, 1.1f, 1.1f, 1f);
|
||||
}
|
||||
BuildTargetGroup group = EditorGUILayout.BeginBuildTargetSelectionGrouping();
|
||||
if (_buildTarget != group)
|
||||
{
|
||||
_buildTarget = group;
|
||||
CacheDefines();
|
||||
}
|
||||
changes |= ShowDefineToggle("Debug Logging", UIFX_LOG);
|
||||
changes |= ShowDefineToggle("Filter Debugging", UIFX_FILTER_DEBUG);
|
||||
changes |= ShowDefineToggle("Filter Force Update in Play Mode", UIFX_FILTERS_FORCE_UPDATE_PLAYMODE);
|
||||
changes |= ShowDefineToggle("Filter Force Update in Edit Mode", UIFX_FILTERS_FORCE_UPDATE_EDITMODE);
|
||||
changes |= ShowDefineToggle("Unreleased Features", UIFX_UNRELEASED);
|
||||
EditorGUILayout.EndBuildTargetSelectionGrouping();
|
||||
GUI.color = Color.white;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
|
||||
}
|
||||
|
||||
_unappliedChanges = changes;
|
||||
|
||||
Links();
|
||||
}
|
||||
|
||||
private void Links()
|
||||
{
|
||||
const string DiscordCommunityUrl = "https://discord.gg/wKRzKAHVUE";
|
||||
const string DocumentationUrl = "https://www.chocdino.com/products/category/components/";
|
||||
const string AssetStoreUrl = "https://assetstore.unity.com/publishers/80225?aid=1100lSvNe";
|
||||
|
||||
GUILayout.Label("Chocolate Dinosaur Links:", EditorStyles.largeLabel);
|
||||
|
||||
if (GUILayout.Button("UIFX Documentation", EditorStyles.miniButton))
|
||||
{
|
||||
Application.OpenURL(DocumentationUrl);
|
||||
}
|
||||
if (GUILayout.Button("Discord Community", EditorStyles.miniButton))
|
||||
{
|
||||
Application.OpenURL(DiscordCommunityUrl);
|
||||
}
|
||||
if (GUILayout.Button("Our Assets", EditorStyles.miniButton))
|
||||
{
|
||||
Application.OpenURL(AssetStoreUrl);
|
||||
}
|
||||
}
|
||||
|
||||
private bool ShowDefineToggle(string label, string define)
|
||||
{
|
||||
bool enabled = HasDefine(define);
|
||||
bool changed = HasDefineChanged(define);
|
||||
if (changed)
|
||||
{
|
||||
label += " *";
|
||||
}
|
||||
|
||||
bool newState = GUILayout.Toggle(enabled, label);
|
||||
if (newState != enabled)
|
||||
{
|
||||
if (newState)
|
||||
{
|
||||
AddDefine(define);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveDefine(define);
|
||||
}
|
||||
}
|
||||
|
||||
return HasDefineChanged(define);
|
||||
}
|
||||
|
||||
private static void ShowEditorPref(GUIContent label, string prefKey, string defaultValue)
|
||||
{
|
||||
var oldValue = EditorPrefs.GetString(prefKey, defaultValue);
|
||||
GUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PrefixLabel(label, EditorStyles.textField);
|
||||
var newValue = EditorGUILayout.TextField(oldValue);
|
||||
if (newValue != oldValue)
|
||||
{
|
||||
EditorPrefs.SetString(prefKey, newValue);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private static void ShowEditorPref(GUIContent label, string prefKey, bool defaultValue)
|
||||
{
|
||||
var oldValue = EditorPrefs.GetBool(prefKey, defaultValue);
|
||||
var newValue = GUILayout.Toggle(oldValue, label);
|
||||
if (newValue != oldValue)
|
||||
{
|
||||
EditorPrefs.SetBool(prefKey, newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a2588906ec7e234419d74d5acae7d54e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 274847
|
||||
packageName: UIFX - Glow Filter
|
||||
packageVersion: 1.9.10
|
||||
assetPath: Assets/ChocDino/UIFX/Editor/Scripts/Common/Preferences.cs
|
||||
uploadId: 833966
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 990985a698e26ef4c8009d73f7f4d56f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,727 @@
|
||||
//--------------------------------------------------------------------------//
|
||||
// Copyright 2023-2025 Chocolate Dinosaur Ltd. All rights reserved. //
|
||||
// For full documentation visit https://www.chocolatedinosaur.com //
|
||||
//--------------------------------------------------------------------------//
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEditor;
|
||||
|
||||
namespace ChocDino.UIFX.Editor
|
||||
{
|
||||
internal class FilterBaseEditor : BaseEditor
|
||||
{
|
||||
protected static readonly string TextMeshProGraphicTypeName = "TMPro.TextMeshProUGUI";
|
||||
protected static readonly string FilterStackTextMeshProFullTypeName = "ChocDino.UIFX.FilterStackTextMeshPro, ChocDino.UIFX.TMP";
|
||||
protected static readonly string FilterStackTextMeshProComponentName = "FilterStackTextMeshPro";
|
||||
|
||||
protected static readonly GUIContent Content_R = new GUIContent("R");
|
||||
protected static readonly GUIContent Content_SpaceCharacter = new GUIContent(" ");
|
||||
protected static readonly GUIContent Content_Size = new GUIContent("Size");
|
||||
protected static readonly GUIContent Content_Color = new GUIContent("Color");
|
||||
protected static readonly GUIContent Content_Colors = new GUIContent("Colors");
|
||||
protected static readonly GUIContent Content_Apply = new GUIContent("Apply");
|
||||
protected static readonly GUIContent Content_Border = new GUIContent("Border");
|
||||
protected static readonly GUIContent Content_Fill = new GUIContent("Fill");
|
||||
protected static readonly GUIContent Content_Preview = new GUIContent("Preview");
|
||||
protected static readonly GUIContent Content_Stop = new GUIContent("Stop");
|
||||
protected static readonly GUIContent Content_Texture = new GUIContent("Texture");
|
||||
protected static readonly GUIContent Content_Gradient = new GUIContent("Gradient");
|
||||
protected static readonly GUIContent Content_Reverse = new GUIContent("Reverse");
|
||||
|
||||
private static readonly GUIContent Content_Debug = new GUIContent("Debug");
|
||||
private static readonly GUIContent Content_Strength = new GUIContent("Strength");
|
||||
private static readonly GUIContent Content_SaveToPNG = new GUIContent("Save to PNG");
|
||||
private static readonly GUIContent Content_BakeToImage = new GUIContent("Bake To Image", "Bake all filters above to an Image component. Baking currently doesn't support: world-space canvas, rotation or scale, and unmatching anchor min/max values, TextMeshPro.");
|
||||
private static readonly GUIContent Content_PreviewTitle= new GUIContent("UIFX - Filters");
|
||||
|
||||
private void ShowSaveToPngButton()
|
||||
{
|
||||
// TODO: Add baking to Image option that bakes to a new GameObject and doesn't destroy the old object
|
||||
// TODO: Convert the image baking buttons into a EditorGUILayout.DropDownToggle()
|
||||
if (GUILayout.Button(Content_SaveToPNG))
|
||||
{
|
||||
foreach (FilterBase filter in this.targets)
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(Application.dataPath + "/../Captures/");
|
||||
string timestamp = System.DateTime.Now.ToString("yyyyMMdd-HHmmss");
|
||||
string filterName = filter.GetType().Name;
|
||||
string path = System.IO.Path.GetFullPath(Application.dataPath + string.Format("/../Captures/Image-{0}-{1}-{2}.png", timestamp, filter.gameObject.name, filterName));
|
||||
if (filter.SaveToPNG(path))
|
||||
{
|
||||
Debug.Log("Saving image to: <b>" + path + "</b>");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Failed to save image to: <b>" + path + "</b>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !UIFX_FILTER_HIDE_INSPECTOR_PREVIEW
|
||||
|
||||
private string GetFilterShortName()
|
||||
{
|
||||
return this.target.GetType().Name;
|
||||
}
|
||||
|
||||
public override GUIContent GetPreviewTitle()
|
||||
{
|
||||
return Content_PreviewTitle;
|
||||
}
|
||||
|
||||
public override bool HasPreviewGUI()
|
||||
{
|
||||
// We can't support multiple targets because the below logic to only show the last item doesn't work
|
||||
if (targets.Length > 1) return false;
|
||||
|
||||
var filter = target as FilterBase;
|
||||
if (!filter.isActiveAndEnabled) return false;
|
||||
|
||||
// Only allow the last ENABLED filter in the stack to preview
|
||||
var filters = filter.gameObject.GetComponents<FilterBase>();
|
||||
FilterBase lastEnabledFilter = null;
|
||||
for (int i = 0; i < filters.Length; i++)
|
||||
{
|
||||
if (filters[i].isActiveAndEnabled && filters[i].IsFilterEnabled() && filters[i].CanSelfRender())
|
||||
{
|
||||
lastEnabledFilter = filters[i];
|
||||
}
|
||||
}
|
||||
return (lastEnabledFilter == filter);
|
||||
}
|
||||
|
||||
public override string GetInfoString()
|
||||
{
|
||||
var filter = target as FilterBase;
|
||||
return filter.GetDebugString();
|
||||
}
|
||||
|
||||
public override void OnPreviewSettings()
|
||||
{
|
||||
ShowSaveToPngButton();
|
||||
}
|
||||
|
||||
public override void OnPreviewGUI(Rect r, GUIStyle background)
|
||||
{
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
var filter = target as FilterBase;
|
||||
EditorGUI.DrawTextureTransparent(r, Texture2D.blackTexture, ScaleMode.StretchToFill);
|
||||
var texture = filter.ResolveToTexture();
|
||||
if (texture)
|
||||
{
|
||||
GUI.DrawTexture(r, texture, ScaleMode.ScaleToFit, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private static void DrawTexture(Texture texture, bool showAlphaBlended)
|
||||
{
|
||||
if (texture)
|
||||
{
|
||||
GUILayout.Label(string.Format("{0} {1}x{2}:{3}", texture.name, texture.width, texture.height, texture.updateCount));
|
||||
|
||||
if (showAlphaBlended)
|
||||
{
|
||||
{
|
||||
Rect r = GUILayoutUtility.GetRect(256f, 256f);
|
||||
EditorGUI.DrawTextureTransparent(r, Texture2D.blackTexture, ScaleMode.StretchToFill);
|
||||
GUI.DrawTexture(r, texture, ScaleMode.ScaleToFit, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
float aspect = (float)texture.width / (float)texture.height;
|
||||
Rect r = GUILayoutUtility.GetAspectRect(aspect * 2f, GUILayout.ExpandWidth(true));
|
||||
Rect rc = r;
|
||||
rc.width /= 2f;
|
||||
GUI.DrawTexture(rc, texture, ScaleMode.ScaleToFit, false);
|
||||
rc.x += rc.width;
|
||||
EditorGUI.DrawTextureAlpha(rc, texture, ScaleMode.ScaleToFit);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Select"))
|
||||
{
|
||||
UnityEditor.Selection.activeObject = texture;
|
||||
}
|
||||
if (GUILayout.Button("Save"))
|
||||
{
|
||||
SaveTexture(texture as RenderTexture);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
private bool CanBakeFiltersToImage(FilterBase filter)
|
||||
{
|
||||
if (!filter.CanApplyFilter()) { return false; }
|
||||
var graphic = filter.GetComponent<Graphic>();
|
||||
if (!graphic) { return false; }
|
||||
|
||||
var graphicTypeName = graphic.GetType().ToString();
|
||||
if (graphicTypeName.Contains(TextMeshProGraphicTypeName)) { return false; }
|
||||
|
||||
var canvas = graphic.canvas;
|
||||
if (!canvas) { return false; }
|
||||
|
||||
// NOTE: In the future when working in canvas space we'll be able to support these
|
||||
if (canvas.renderMode == RenderMode.WorldSpace) { return false; }
|
||||
|
||||
var xform = filter.GetComponent<RectTransform>();
|
||||
if (!xform) { return false; }
|
||||
|
||||
// NOTE: In the future when working in canvas space we'll be able to support these
|
||||
if (xform.localRotation != Quaternion.identity) { return false;}
|
||||
if (xform.localScale != Vector3.one) { return false;}
|
||||
|
||||
// NOTE: Currently just haven't figured out the math for this case where anchor min/max are different
|
||||
if (xform.anchorMin.x != xform.anchorMax.x) { return false; }
|
||||
if (xform.anchorMin.y != xform.anchorMax.y) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool CanSaveFilterToPng(FilterBase filter)
|
||||
{
|
||||
if (!filter.CanApplyFilter()) { return false; }
|
||||
var graphic = filter.GetComponent<Graphic>();
|
||||
if (!graphic) { return false; }
|
||||
|
||||
var graphicTypeName = graphic.GetType().ToString();
|
||||
if (graphicTypeName.Contains(TextMeshProGraphicTypeName)) { return false; }
|
||||
|
||||
var canvas = graphic.canvas;
|
||||
if (!canvas) { return false; }
|
||||
|
||||
// NOTE: In the future when working in canvas space we'll be able to support these
|
||||
if (canvas.renderMode == RenderMode.WorldSpace) { return false; }
|
||||
|
||||
var xform = filter.GetComponent<RectTransform>();
|
||||
if (!xform) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool BakeFiltersToImage(FilterBase filter, bool makeCopy)
|
||||
{
|
||||
Vector2 anchorOffset = Vector2.zero;
|
||||
{
|
||||
var graphic = filter.GetComponent<Graphic>();
|
||||
if (graphic)
|
||||
{
|
||||
var xform = graphic.GetComponent<RectTransform>();
|
||||
Rect r = filter.GetLocalRect();
|
||||
r.max += filter._lastRenderAdjustRightUp;
|
||||
r.min -= filter._lastRenderAdjustLeftDown;
|
||||
anchorOffset.x = r.x + r.width * xform.pivot.x + xform.anchoredPosition.x;
|
||||
anchorOffset.y = r.y + r.height * xform.pivot.y + xform.anchoredPosition.y;
|
||||
}
|
||||
}
|
||||
|
||||
// Bake to new texture asset
|
||||
string uniqueFileName;
|
||||
{
|
||||
string timestamp = System.DateTime.Now.ToString("yyyyMMdd-HHmmss");
|
||||
string subFolder = Preferences.BakedImageSubfolder;
|
||||
subFolder = System.IO.Path.Combine("Assets/", subFolder);
|
||||
if (!subFolder.EndsWith("/")) { subFolder += "/"; }
|
||||
subFolder = System.IO.Path.Combine(subFolder, string.Format("Baked-{0}-{1}.png", timestamp, filter.gameObject.name));
|
||||
var fullPath = System.IO.Path.GetFullPath(Application.dataPath + "/../" + subFolder);
|
||||
string directoryPath = System.IO.Path.GetDirectoryName(fullPath);
|
||||
if (!System.IO.Directory.Exists(directoryPath))
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(directoryPath);
|
||||
}
|
||||
uniqueFileName = AssetDatabase.GenerateUniqueAssetPath(subFolder);
|
||||
fullPath = System.IO.Path.GetFullPath(Application.dataPath + "/../" + uniqueFileName);
|
||||
AssetDatabase.StartAssetEditing();
|
||||
filter.SaveToPNG(fullPath);
|
||||
AssetDatabase.StopAssetEditing();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
// Modify importer settings for new texture asset
|
||||
TextureImporter importer = (TextureImporter)AssetImporter.GetAtPath(uniqueFileName);
|
||||
if (importer)
|
||||
{
|
||||
importer.textureType = TextureImporterType.Sprite;
|
||||
importer.textureCompression = TextureImporterCompression.Uncompressed;
|
||||
importer.npotScale = TextureImporterNPOTScale.None;
|
||||
importer.alphaIsTransparency = true;
|
||||
importer.mipmapEnabled = false;
|
||||
importer.sRGBTexture = true;
|
||||
|
||||
TextureImporterSettings settings = new TextureImporterSettings();
|
||||
importer.ReadTextureSettings(settings);
|
||||
settings.spriteMode = (int)SpriteImportMode.Single;
|
||||
settings.spriteMeshType = SpriteMeshType.FullRect;
|
||||
settings.spriteGenerateFallbackPhysicsShape = false;
|
||||
importer.SetTextureSettings(settings);
|
||||
|
||||
EditorUtility.SetDirty(importer);
|
||||
importer.SaveAndReimport();
|
||||
AssetDatabase.WriteImportSettingsIfDirty(uniqueFileName);
|
||||
}
|
||||
|
||||
// Get the asset
|
||||
var textureAsset = (Texture2D)AssetDatabase.LoadAssetAtPath(uniqueFileName, typeof(Texture2D));
|
||||
Sprite spriteAsset = null;
|
||||
{
|
||||
Object[] objs = AssetDatabase.LoadAllAssetRepresentationsAtPath(uniqueFileName);
|
||||
if (objs != null)
|
||||
{
|
||||
foreach (Object obj in objs)
|
||||
{
|
||||
if (obj.GetType() == typeof(Sprite))
|
||||
{
|
||||
spriteAsset = obj as Sprite;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GameObject targetGo = filter.gameObject;
|
||||
|
||||
// Make a copy of the GameObject (optional)
|
||||
if (makeCopy)
|
||||
{
|
||||
targetGo = (GameObject)GameObject.Instantiate(filter.gameObject, filter.transform.parent, instantiateInWorldSpace:false);
|
||||
targetGo.name = filter.gameObject.name + "-Baked";
|
||||
}
|
||||
|
||||
// Get the component index of the original filter
|
||||
int filterComponentIndex = 0;
|
||||
{
|
||||
Component[] sourceComponents = filter.gameObject.GetComponents<Component>();
|
||||
filterComponentIndex = System.Array.IndexOf(sourceComponents, filter);
|
||||
}
|
||||
|
||||
Component[] components = targetGo.GetComponents<Component>();
|
||||
|
||||
int oldGraphicIndex = 0;
|
||||
bool isRaycastTarget = false;
|
||||
// Remove the previous Graphic
|
||||
{
|
||||
var graphic = targetGo.GetComponent<Graphic>();
|
||||
if (graphic)
|
||||
{
|
||||
isRaycastTarget = graphic.raycastTarget;
|
||||
oldGraphicIndex = System.Array.IndexOf(components, graphic);
|
||||
Undo.DestroyObjectImmediate(graphic);
|
||||
}
|
||||
}
|
||||
|
||||
// Add RawImage component and assign texture
|
||||
var image = Undo.AddComponent<RawImage>(targetGo);
|
||||
//image.sprite = spriteAsset;
|
||||
image.texture = textureAsset;
|
||||
image.raycastTarget = isRaycastTarget;
|
||||
//image.preserveAspect = true;
|
||||
image.maskable = false;
|
||||
float scale = image.canvas.scaleFactor;
|
||||
|
||||
// Move RawImage component to order position of old Graphic
|
||||
int newGraphicIndex = (components.Length - 1);
|
||||
int moveDelta = Mathf.Abs(oldGraphicIndex - newGraphicIndex);
|
||||
for (int i = 0; i < moveDelta; i++)
|
||||
{
|
||||
if (newGraphicIndex > oldGraphicIndex) { UnityEditorInternal.ComponentUtility.MoveComponentUp(image); }
|
||||
else { UnityEditorInternal.ComponentUtility.MoveComponentDown(image); }
|
||||
}
|
||||
|
||||
// Change the RectTransform
|
||||
{
|
||||
var xform = image.rectTransform;
|
||||
xform.sizeDelta = new Vector2(textureAsset.width / scale, textureAsset.height / scale);
|
||||
xform.anchoredPosition = anchorOffset;
|
||||
}
|
||||
|
||||
// Remove all FilterBase and IMeshModifiers that affect this render
|
||||
{
|
||||
int componentIndex = 0;
|
||||
foreach (var component in components)
|
||||
{
|
||||
if (componentIndex <= filterComponentIndex)
|
||||
{
|
||||
if (component is FilterBase || component is IMeshModifier)
|
||||
{
|
||||
Undo.DestroyObjectImmediate(component);
|
||||
}
|
||||
}
|
||||
componentIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// Select the texture so the user knows where it exists
|
||||
//Selection.activeObject = textureAsset;
|
||||
|
||||
//Object prevSelection = Selection.activeObject;
|
||||
// Select the old or new GameObject
|
||||
if (makeCopy)
|
||||
{
|
||||
Selection.activeGameObject = targetGo;
|
||||
}
|
||||
//else
|
||||
{
|
||||
// Selection.activeObject = prevSelection;
|
||||
}
|
||||
|
||||
//Undo.DestroyObjectImmediate(filter);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ShowBakeFiltersToImageDialog(FilterBase filter)
|
||||
{
|
||||
bool result = false;
|
||||
int option = EditorUtility.DisplayDialogComplex("Bake To Image", "Do you want to override the current GameObject or bake to a copy of it?", "Override", "Cancel", "Make Copy");
|
||||
switch (option)
|
||||
{
|
||||
// Override.
|
||||
case 0:
|
||||
result = BakeFiltersToImage(filter, makeCopy:false);
|
||||
break;
|
||||
// Make Copy.
|
||||
case 2:
|
||||
result = BakeFiltersToImage(filter, makeCopy:true);
|
||||
break;
|
||||
// Cancel.
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
Debug.LogError("Unrecognized option.");
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal bool OnInspectorGUI_Baking(FilterBase filter)
|
||||
{
|
||||
if (!Preferences.ShowFooterBakeButtons)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
GUILayout.BeginHorizontal();
|
||||
bool wasEnabled = GUI.enabled;
|
||||
GUI.enabled = wasEnabled & CanBakeFiltersToImage(filter);
|
||||
if (GUILayout.Button(Content_BakeToImage))
|
||||
{
|
||||
// Use a delay because we're showing a dialog which breaks IMGUI flow
|
||||
EditorApplication.delayCall += () =>
|
||||
{
|
||||
ShowBakeFiltersToImageDialog(filter);
|
||||
};
|
||||
}
|
||||
GUI.enabled = wasEnabled & CanSaveFilterToPng(filter);
|
||||
ShowSaveToPngButton();
|
||||
GUI.enabled = wasEnabled;
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns true if checks fail and the rest of the inspector shouldn't be shown
|
||||
internal bool OnInspectorGUI_Check(FilterBase filter)
|
||||
{
|
||||
bool result = false;
|
||||
var graphic = filter.GraphicComponent;
|
||||
if (graphic)
|
||||
{
|
||||
// Check for TextMeshPro in the selection
|
||||
bool selectionHasTextMeshPro = false;
|
||||
foreach (var obj in this.targets)
|
||||
{
|
||||
var filterInstance = obj as FilterBase;
|
||||
if (filterInstance.GraphicComponent)
|
||||
{
|
||||
if (filterInstance.GraphicComponent.GetType().ToString().Contains(TextMeshProGraphicTypeName))
|
||||
{
|
||||
selectionHasTextMeshPro = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectionHasTextMeshPro)
|
||||
{
|
||||
#if !UIFX_TMPRO
|
||||
result = true;
|
||||
EditorGUILayout.HelpBox("TextMeshPro not detected...", MessageType.Error, true);
|
||||
EditorGUILayout.Space();
|
||||
#else
|
||||
bool needsFilterStackTMP = false;
|
||||
foreach (var obj in this.targets)
|
||||
{
|
||||
var filterInstance = obj as FilterBase;
|
||||
if (filterInstance.GraphicComponent)
|
||||
{
|
||||
if (filterInstance.GraphicComponent.GetType().ToString().Contains(TextMeshProGraphicTypeName))
|
||||
{
|
||||
if (null == filterInstance.gameObject.GetComponent(FilterStackTextMeshProComponentName))
|
||||
{
|
||||
needsFilterStackTMP = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needsFilterStackTMP)
|
||||
{
|
||||
result = true;
|
||||
EditorGUILayout.HelpBox("The FilterStackTextMeshPro component is required to apply filters to TextMeshPro", MessageType.Error, true);
|
||||
if (GUILayout.Button("Add FilterStackTextMeshPro"))
|
||||
{
|
||||
var filterStackType = System.Type.GetType(FilterStackTextMeshProFullTypeName, false);
|
||||
if (filterStackType != null)
|
||||
{
|
||||
foreach (var obj in this.targets)
|
||||
{
|
||||
var filterInstance = obj as FilterBase;
|
||||
if (filterInstance.GraphicComponent)
|
||||
{
|
||||
if (filterInstance.GraphicComponent.GetType().ToString().Contains(TextMeshProGraphicTypeName))
|
||||
{
|
||||
if (null == filterInstance.gameObject.GetComponent(FilterStackTextMeshProComponentName))
|
||||
{
|
||||
filterInstance.gameObject.AddComponent(filterStackType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Couldn't find " + FilterStackTextMeshProFullTypeName);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Warn user about out of range Canvas.planeDistance
|
||||
if (filter.IsCanvasPlaneDistanceOutOfRange())
|
||||
{
|
||||
EditorGUILayout.HelpBox(FilterBase.s_warnCanvasPlaneDistanceCullingMessage, MessageType.Warning, true);
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
if (filter.IsTextureTooLarge())
|
||||
{
|
||||
EditorGUILayout.HelpBox("Requested texture is larger than the supported size of " + Filters.GetMaxiumumTextureSize() + ", rescaling texture to supported size, this can lead to lower texture quality. Consider invstigating why such a large texture is required.", MessageType.Error, true);
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static void OnInspectorGUI_Debug(FilterBase filter)
|
||||
{
|
||||
#if UIFX_FILTER_DEBUG
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
GUILayout.Label(Content_Debug, EditorStyles.boldLabel);
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.TextArea(filter.GetDebugString());
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
Texture[] textures = filter.GetDebugTextures();
|
||||
foreach (var texture in textures)
|
||||
{
|
||||
DrawTexture(texture, false);
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
if (filter.isActiveAndEnabled)
|
||||
{
|
||||
DrawTexture(filter.ResolveToTexture(), true);
|
||||
if (GUILayout.Button("Save Final"))
|
||||
{
|
||||
filter.SaveToPNG(Application.dataPath + "/../final.png");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static void PropertyReset_Slider(SerializedProperty prop, GUIContent label, float min, float max, float resetValue)
|
||||
{
|
||||
float buttonWidth = 0f;
|
||||
if (EditorGUIUtility.wideMode)
|
||||
{
|
||||
buttonWidth = GUI.skin.button.CalcSize(Content_R).x;
|
||||
}
|
||||
|
||||
Rect rect = EditorGUILayout.GetControlRect(true);
|
||||
EditorGUI.BeginProperty(rect, label, prop);
|
||||
|
||||
rect.xMax -= buttonWidth;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
float newValue = EditorGUI.Slider(rect, label, prop.floatValue, min, max);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
prop.floatValue = newValue;
|
||||
}
|
||||
|
||||
if (EditorGUIUtility.wideMode)
|
||||
{
|
||||
rect.xMin += rect.width;
|
||||
rect.xMax += buttonWidth;
|
||||
|
||||
{
|
||||
bool wasEnabled = GUI.enabled;
|
||||
GUI.enabled = (prop.floatValue != resetValue);
|
||||
if (GUI.Button(rect, Content_R))
|
||||
{
|
||||
prop.floatValue = resetValue;
|
||||
}
|
||||
GUI.enabled = wasEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
|
||||
internal static void PropertyReset_Float(SerializedProperty prop, float resetValue)
|
||||
{
|
||||
if (!EditorGUIUtility.wideMode)
|
||||
{
|
||||
EditorGUILayout.PropertyField(prop);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PropertyField(prop);
|
||||
bool wasEnabled = GUI.enabled;
|
||||
GUI.enabled = (prop.floatValue != resetValue);
|
||||
if (GUILayout.Button(Content_R, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
prop.floatValue = resetValue;
|
||||
}
|
||||
GUI.enabled = wasEnabled;
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DrawStrengthProperty(SerializedProperty prop)
|
||||
{
|
||||
Rect rect = EditorGUILayout.GetControlRect(true);
|
||||
EditorGUI.BeginProperty(rect, Content_Strength, prop);
|
||||
|
||||
float strength = prop.floatValue;
|
||||
if (DrawStrengthProperty(rect, ref strength))
|
||||
{
|
||||
prop.floatValue = strength;
|
||||
}
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
|
||||
internal static bool DrawStrengthProperty(ref float value)
|
||||
{
|
||||
bool hasChanged = false;
|
||||
Rect rect = EditorGUILayout.GetControlRect(true);
|
||||
|
||||
if (DrawStrengthProperty(rect, ref value))
|
||||
{
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
return hasChanged;
|
||||
}
|
||||
|
||||
internal static bool DrawStrengthProperty(Rect rect, ref float value)
|
||||
{
|
||||
bool changed = false;
|
||||
const float resetValue = 1f;
|
||||
|
||||
float buttonWidth = 0f;
|
||||
if (EditorGUIUtility.wideMode)
|
||||
{
|
||||
buttonWidth = GUI.skin.button.CalcSize(Content_R).x;
|
||||
}
|
||||
|
||||
bool isColored = false;
|
||||
if (value < 1f)
|
||||
{
|
||||
isColored = true;
|
||||
if (value > 0f)
|
||||
{
|
||||
GUI.backgroundColor = Color.yellow;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.backgroundColor = Color.red;
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
rect.xMax -= buttonWidth;
|
||||
float newValue = EditorGUI.Slider(rect, Content_Strength, value, 0f, 1f);
|
||||
|
||||
if (EditorGUIUtility.wideMode)
|
||||
{
|
||||
rect.xMin += rect.width;
|
||||
rect.xMax += buttonWidth;
|
||||
bool wasEnabled = GUI.enabled;
|
||||
GUI.enabled = (value != resetValue);
|
||||
if (GUI.Button(rect, Content_R))
|
||||
{
|
||||
value = newValue = resetValue;
|
||||
changed = true;
|
||||
}
|
||||
GUI.enabled = wasEnabled;
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
value = newValue;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (isColored)
|
||||
{
|
||||
GUI.backgroundColor = Color.white;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
internal static void DrawDualColors(SerializedProperty col1, SerializedProperty col2, GUIContent label)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PrefixLabel(label, EditorStyles.colorField);
|
||||
EditorGUI.indentLevel-=1; // NOTE: This seems to be a bug in Unity where it shows the indentation with ColorFields, so we have to remove it manually...
|
||||
EditorGUILayout.PropertyField(col1, GUIContent.none);
|
||||
EditorGUILayout.PropertyField(col2, GUIContent.none);
|
||||
EditorGUI.indentLevel+=1;
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
protected static void SaveTexture(RenderTexture texture)
|
||||
{
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
Texture2D rwTexture = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, mipChain: false, linear: false, createUninitialized: true);
|
||||
#else
|
||||
Texture2D rwTexture = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, mipChain: false);
|
||||
#endif
|
||||
|
||||
TextureUtils.WriteToPNG(texture, rwTexture, Application.dataPath + "/../SavedScreen.png");
|
||||
ObjectHelper.Destroy(ref rwTexture);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91387ed1db237a14c997b34ed9a7f8ae
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 274847
|
||||
packageName: UIFX - Glow Filter
|
||||
packageVersion: 1.9.10
|
||||
assetPath: Assets/ChocDino/UIFX/Editor/Scripts/Filters/FilterBaseEditor.cs
|
||||
uploadId: 833966
|
||||
@@ -0,0 +1,211 @@
|
||||
//--------------------------------------------------------------------------//
|
||||
// Copyright 2023-2025 Chocolate Dinosaur Ltd. All rights reserved. //
|
||||
// For full documentation visit https://www.chocolatedinosaur.com //
|
||||
//--------------------------------------------------------------------------//
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace ChocDino.UIFX.Editor
|
||||
{
|
||||
[CustomEditor(typeof(GlowFilter), true)]
|
||||
[CanEditMultipleObjects]
|
||||
internal class GlowFilterEditor : FilterBaseEditor
|
||||
{
|
||||
|
||||
private static readonly AboutInfo s_aboutInfo =
|
||||
new AboutInfo(s_aboutHelp, "UIFX - Glow Filter\n© Chocolate Dinosaur Ltd", "uifx-logo-glow-filter")
|
||||
{
|
||||
sections = new AboutSection[]
|
||||
{
|
||||
new AboutSection("Asset Guides")
|
||||
{
|
||||
buttons = new AboutButton[]
|
||||
{
|
||||
new AboutButton("User Guide", "https://www.chocdino.com/products/uifx/glow-filter/about/"),
|
||||
new AboutButton("Scripting Guide", "https://www.chocdino.com/products/uifx/glow-filter/scripting/"),
|
||||
new AboutButton("Components Reference", "https://www.chocdino.com/products/uifx/glow-filter/components/glow-filter/"),
|
||||
new AboutButton("API Reference", "https://www.chocdino.com/products/uifx/glow-filter/API/ChocDino.UIFX/"),
|
||||
}
|
||||
},
|
||||
new AboutSection("Unity Asset Store Review\r\n<color=#ffd700>★★★★☆</color>")
|
||||
{
|
||||
buttons = new AboutButton[]
|
||||
{
|
||||
new AboutButton("Review <b>UIFX - Glow Filter</b>", "https://assetstore.unity.com/packages/slug/274847?aid=1100lSvNe#reviews"),
|
||||
new AboutButton("Review <b>UIFX Bundle</b>", AssetStoreBundleReviewUrl),
|
||||
}
|
||||
},
|
||||
new AboutSection("UIFX Support")
|
||||
{
|
||||
buttons = new AboutButton[]
|
||||
{
|
||||
new AboutButton("Discord Community", DiscordUrl),
|
||||
new AboutButton("Post to Unity Discussions", ""),
|
||||
new AboutButton("Post Issues to GitHub", GithubUrl),
|
||||
new AboutButton("Email Us", SupportEmailUrl),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static readonly AboutToolbar s_aboutToolbar = new AboutToolbar(new AboutInfo[] { s_upgradeToBundle, s_aboutInfo } );
|
||||
|
||||
private static readonly GUIContent Content_Shape = new GUIContent("Shape");
|
||||
private static readonly GUIContent Content_Falloff = new GUIContent("Falloff");
|
||||
private static readonly GUIContent Content_Distance = new GUIContent("Distance");
|
||||
private static readonly GUIContent Content_Mode = new GUIContent("Mode");
|
||||
private static readonly GUIContent Content_Curve = new GUIContent("Curve");
|
||||
private static readonly GUIContent Content_Energy = new GUIContent("Energy");
|
||||
private static readonly GUIContent Content_Power = new GUIContent("Power");
|
||||
private static readonly GUIContent Content_Gamma = new GUIContent("Gamma");
|
||||
private static readonly GUIContent Content_Offset = new GUIContent("Offset");
|
||||
|
||||
private SerializedProperty _propEdgeSide;
|
||||
private SerializedProperty _propDistanceShape;
|
||||
private SerializedProperty _propMaxDistance;
|
||||
private SerializedProperty _propReuseDistanceMap;
|
||||
private SerializedProperty _propFalloffMode;
|
||||
private SerializedProperty _propExpFalloffEnergy;
|
||||
private SerializedProperty _propExpFalloffPower;
|
||||
private SerializedProperty _propExpFalloffOffset;
|
||||
private SerializedProperty _propFalloffCurve;
|
||||
private SerializedProperty _propFalloffCurveGamma;
|
||||
private SerializedProperty _propFillMode;
|
||||
private SerializedProperty _propColor;
|
||||
private SerializedProperty _propGradient;
|
||||
private SerializedProperty _propGradientTexture;
|
||||
private SerializedProperty _propGradientOffset;
|
||||
private SerializedProperty _propGradientGamma;
|
||||
private SerializedProperty _propGradientReverse;
|
||||
private SerializedProperty _propBlur;
|
||||
private SerializedProperty _propSourceAlpha;
|
||||
private SerializedProperty _propAdditive;
|
||||
private SerializedProperty _propNoiseScale;
|
||||
private SerializedProperty _propStrength;
|
||||
private SerializedProperty _propRenderSpace;
|
||||
private SerializedProperty _propExpand;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
_propDistanceShape = VerifyFindProperty("_distanceShape");
|
||||
_propMaxDistance = VerifyFindProperty("_maxDistance");
|
||||
_propEdgeSide = VerifyFindProperty("_edgeSide");
|
||||
_propBlur = VerifyFindProperty("_blur");
|
||||
_propReuseDistanceMap = VerifyFindProperty("_reuseDistanceMap");
|
||||
|
||||
_propFalloffMode = VerifyFindProperty("_falloffMode");
|
||||
_propExpFalloffEnergy = VerifyFindProperty("_expFalloffEnergy");
|
||||
_propExpFalloffPower = VerifyFindProperty("_expFalloffPower");
|
||||
_propExpFalloffOffset = VerifyFindProperty("_expFalloffOffset");
|
||||
_propFalloffCurve = VerifyFindProperty("_falloffCurve");
|
||||
_propFalloffCurveGamma = VerifyFindProperty("_falloffCurveGamma");
|
||||
|
||||
_propFillMode = VerifyFindProperty("_fillMode");
|
||||
_propColor = VerifyFindProperty("_color");
|
||||
_propGradient = VerifyFindProperty("_gradient");
|
||||
_propGradientTexture = VerifyFindProperty("_gradientTexture");
|
||||
_propGradientOffset = VerifyFindProperty("_gradientOffset");
|
||||
_propGradientGamma = VerifyFindProperty("_gradientGamma");
|
||||
_propGradientReverse = VerifyFindProperty("_gradientReverse");
|
||||
|
||||
_propAdditive = VerifyFindProperty("_additive");
|
||||
_propNoiseScale = VerifyFindProperty("_noiseScale");
|
||||
_propSourceAlpha = VerifyFindProperty("_sourceAlpha");
|
||||
_propStrength = VerifyFindProperty("_strength");
|
||||
_propRenderSpace = VerifyFindProperty("_renderSpace");
|
||||
_propExpand = VerifyFindProperty("_expand");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
s_aboutToolbar.OnGUI();
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
var filter = this.target as FilterBase;
|
||||
|
||||
if (OnInspectorGUI_Check(filter))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GUILayout.Label(Content_Distance, EditorStyles.boldLabel);
|
||||
EditorGUI.indentLevel++;
|
||||
EnumAsToolbar(_propEdgeSide);
|
||||
EnumAsToolbar(_propDistanceShape, Content_Shape);
|
||||
EditorGUILayout.PropertyField(_propMaxDistance);
|
||||
EditorGUILayout.PropertyField(_propBlur);
|
||||
EditorGUILayout.PropertyField(_propReuseDistanceMap);
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
GUILayout.Label(Content_Falloff, EditorStyles.boldLabel);
|
||||
EditorGUI.indentLevel++;
|
||||
EnumAsToolbar(_propFalloffMode, Content_Mode);
|
||||
if (_propFalloffMode.enumValueIndex == (int)GlowFalloffMode.Exponential)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propExpFalloffEnergy, Content_Energy);
|
||||
EditorGUILayout.PropertyField(_propExpFalloffPower, Content_Power);
|
||||
EditorGUILayout.PropertyField(_propExpFalloffOffset, Content_Offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propFalloffCurve, Content_Curve);
|
||||
// Show a warning if curve key values of out of sensible range.
|
||||
// NOTE: We have to detect whether the curve window has focus currently, otherwise if the HelpBox() appears
|
||||
// while dragging curve keys, it can cause the keys to not update.
|
||||
if (!EditorHelper.IsEditingCurve())
|
||||
{
|
||||
if (_propFalloffCurve.animationCurveValue.HasOutOfRangeValues(0f, 1f, 0f))
|
||||
{
|
||||
EditorGUILayout.HelpBox("Some curve points are outside of the range [0..1]. This might be fine, or could lead to unexpected results.", MessageType.Warning, true);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.PropertyField(_propFalloffCurveGamma, Content_Gamma);
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
GUILayout.Label(Content_Fill, EditorStyles.boldLabel);
|
||||
EditorGUI.indentLevel++;
|
||||
EnumAsToolbar(_propFillMode, Content_Mode);
|
||||
if (_propFillMode.enumValueIndex == (int)GlowFillMode.Color)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propColor);
|
||||
}
|
||||
if (_propFillMode.enumValueIndex == (int)GlowFillMode.Texture)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propGradientTexture, Content_Texture);
|
||||
EditorGUILayout.PropertyField(_propGradientOffset, Content_Offset);
|
||||
EditorGUILayout.PropertyField(_propGradientGamma, Content_Gamma);
|
||||
EditorGUILayout.PropertyField(_propGradientReverse, Content_Reverse);
|
||||
}
|
||||
else if (_propFillMode.enumValueIndex == (int)GlowFillMode.Gradient)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propGradient);
|
||||
EditorGUILayout.PropertyField(_propGradientOffset, Content_Offset);
|
||||
EditorGUILayout.PropertyField(_propGradientGamma, Content_Gamma);
|
||||
EditorGUILayout.PropertyField(_propGradientReverse, Content_Reverse);
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
GUILayout.Label(Content_Apply, EditorStyles.boldLabel);
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(_propNoiseScale);
|
||||
EditorGUILayout.PropertyField(_propAdditive);
|
||||
EditorGUILayout.PropertyField(_propSourceAlpha);
|
||||
EnumAsToolbarCompact(_propRenderSpace);
|
||||
EnumAsToolbarCompact(_propExpand);
|
||||
DrawStrengthProperty(_propStrength);
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
if (OnInspectorGUI_Baking(filter))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FilterBaseEditor.OnInspectorGUI_Debug(filter);
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af4ccd4e17aaeae4c9eadf9bed968d3e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 274847
|
||||
packageName: UIFX - Glow Filter
|
||||
packageVersion: 1.9.10
|
||||
assetPath: Assets/ChocDino/UIFX/Editor/Scripts/Filters/GlowFilterEditor.cs
|
||||
uploadId: 833966
|
||||
Reference in New Issue
Block a user