优化
This commit is contained in:
parent
d8fd91d32c
commit
761b7b1827
@ -16,6 +16,50 @@ namespace AlicizaX.UI.Extension.Editor
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
public static void DrawProperty(SerializedProperty property, GUISkin skin, string content,
|
||||
Action<object, object> changeCallBack)
|
||||
{
|
||||
GUILayout.BeginHorizontal(EditorStyles.helpBox);
|
||||
EditorGUILayout.LabelField(new GUIContent(content), skin.FindStyle("Text"), GUILayout.Width(120));
|
||||
|
||||
// 保存变化前的值
|
||||
object oldValue = SerializedPropertyUtility.GetPropertyValue(property);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(property, new GUIContent(""));
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
// 获取变化后的值
|
||||
object newValue = SerializedPropertyUtility.GetPropertyValue(property);
|
||||
changeCallBack?.Invoke(oldValue, newValue);
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
public static void DrawProperty<T>(SerializedProperty property, GUISkin skin, string content,
|
||||
Action<T, T> changeCallBack, T defaultValue = default(T))
|
||||
{
|
||||
GUILayout.BeginHorizontal(EditorStyles.helpBox);
|
||||
EditorGUILayout.LabelField(new GUIContent(content), skin.FindStyle("Text"), GUILayout.Width(120));
|
||||
|
||||
// 保存变化前的值
|
||||
T oldValue = SerializedPropertyUtility.GetPropertyValue<T>(property, defaultValue);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(property, new GUIContent(""));
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
// 获取变化后的值
|
||||
T newValue = SerializedPropertyUtility.GetPropertyValue<T>(property, defaultValue);
|
||||
changeCallBack?.Invoke(oldValue, newValue);
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
public static void DrawProperty(SerializedProperty property, GUISkin skin, string content, string btnName, Action callback)
|
||||
{
|
||||
GUILayout.BeginHorizontal(EditorStyles.helpBox);
|
||||
|
||||
102
Editor/Helper/SerializedPropertyUtility.cs
Normal file
102
Editor/Helper/SerializedPropertyUtility.cs
Normal file
@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public static class SerializedPropertyUtility
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取SerializedProperty的值(返回object类型)
|
||||
/// </summary>
|
||||
public static object GetPropertyValue(SerializedProperty property)
|
||||
{
|
||||
if (property == null) return null;
|
||||
|
||||
switch (property.propertyType)
|
||||
{
|
||||
case SerializedPropertyType.Integer:
|
||||
return property.intValue;
|
||||
case SerializedPropertyType.Boolean:
|
||||
return property.boolValue;
|
||||
case SerializedPropertyType.Float:
|
||||
return property.floatValue;
|
||||
case SerializedPropertyType.String:
|
||||
return property.stringValue;
|
||||
case SerializedPropertyType.Vector2:
|
||||
return property.vector2Value;
|
||||
case SerializedPropertyType.Vector3:
|
||||
return property.vector3Value;
|
||||
case SerializedPropertyType.Vector4:
|
||||
return property.vector4Value;
|
||||
case SerializedPropertyType.Quaternion:
|
||||
return property.quaternionValue;
|
||||
case SerializedPropertyType.Color:
|
||||
return property.colorValue;
|
||||
case SerializedPropertyType.ObjectReference:
|
||||
return property.objectReferenceValue;
|
||||
case SerializedPropertyType.Enum:
|
||||
return property.enumValueIndex;
|
||||
case SerializedPropertyType.Vector2Int:
|
||||
return property.vector2IntValue;
|
||||
case SerializedPropertyType.Vector3Int:
|
||||
return property.vector3IntValue;
|
||||
case SerializedPropertyType.Rect:
|
||||
return property.rectValue;
|
||||
case SerializedPropertyType.RectInt:
|
||||
return property.rectIntValue;
|
||||
case SerializedPropertyType.Bounds:
|
||||
return property.boundsValue;
|
||||
case SerializedPropertyType.BoundsInt:
|
||||
return property.boundsIntValue;
|
||||
case SerializedPropertyType.AnimationCurve:
|
||||
return property.animationCurveValue;
|
||||
case SerializedPropertyType.Generic:
|
||||
default:
|
||||
// 对于不支持的类型或复杂类型,返回null或尝试其他处理
|
||||
Debug.LogWarning($"Unsupported property type: {property.propertyType}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取SerializedProperty的值(泛型版本)
|
||||
/// </summary>
|
||||
public static T GetPropertyValue<T>(SerializedProperty property, T defaultValue = default(T))
|
||||
{
|
||||
try
|
||||
{
|
||||
object value = GetPropertyValue(property);
|
||||
if (value == null) return defaultValue;
|
||||
|
||||
// 如果类型匹配,直接返回
|
||||
if (value is T typedValue)
|
||||
return typedValue;
|
||||
|
||||
// 尝试类型转换
|
||||
return (T)Convert.ChangeType(value, typeof(T));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning($"Failed to get property value as type {typeof(T).Name}: {e.Message}");
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 安全地获取属性值,返回是否成功
|
||||
/// </summary>
|
||||
public static bool TryGetPropertyValue<T>(SerializedProperty property, out T value, T defaultValue = default(T))
|
||||
{
|
||||
value = defaultValue;
|
||||
|
||||
try
|
||||
{
|
||||
value = GetPropertyValue<T>(property, defaultValue);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Editor/Helper/SerializedPropertyUtility.cs.meta
Normal file
3
Editor/Helper/SerializedPropertyUtility.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c7a9c6164c04b319c042aeee04ee262
|
||||
timeCreated: 1760409703
|
||||
@ -27,8 +27,6 @@ internal class UXButtonEditor : Editor
|
||||
private SerializedProperty m_TransitionData;
|
||||
private SerializedProperty m_ChildTransitions;
|
||||
|
||||
private UXGroup group;
|
||||
private int m_ButtonMode;
|
||||
private SerializedProperty m_SelectionState;
|
||||
|
||||
private ReorderableList m_ChildTransitionList;
|
||||
@ -57,9 +55,6 @@ internal class UXButtonEditor : Editor
|
||||
m_ChildTransitions = serializedObject.FindProperty("m_ChildTransitions");
|
||||
m_SelectionState = serializedObject.FindProperty("m_SelectionState");
|
||||
|
||||
group = (UXGroup)m_UXGroup.objectReferenceValue;
|
||||
m_ButtonMode = m_Mode.enumValueIndex;
|
||||
|
||||
hoverAudioClip = serializedObject.FindProperty("hoverAudioClip");
|
||||
clickAudioClip = serializedObject.FindProperty("clickAudioClip");
|
||||
|
||||
@ -187,7 +182,22 @@ internal class UXButtonEditor : Editor
|
||||
private void DrawGraphicsTab()
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(EditorApplication.isPlaying);
|
||||
EditorGUILayout.PropertyField(m_Mode);
|
||||
var modeType = (ButtonModeType)EditorGUILayout.EnumPopup("Mode", (ButtonModeType)m_Mode.enumValueIndex);
|
||||
if (modeType != (ButtonModeType)m_Mode.enumValueIndex)
|
||||
{
|
||||
if (modeType == ButtonModeType.Normal)
|
||||
{
|
||||
ResetEventProperty(m_OnValueChanged);
|
||||
m_UXGroup.objectReferenceValue = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetEventProperty(m_OnClick);
|
||||
}
|
||||
|
||||
m_Mode.enumValueIndex = (int)modeType;
|
||||
}
|
||||
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
var interactable = GUILayoutHelper.DrawToggle(m_Interactable.boolValue, customSkin, "Interactable");
|
||||
@ -196,6 +206,7 @@ internal class UXButtonEditor : Editor
|
||||
mTarget.Interactable = interactable;
|
||||
m_SelectionState.enumValueIndex = interactable ? 0 : 4;
|
||||
}
|
||||
|
||||
m_Interactable.boolValue = interactable;
|
||||
|
||||
GUILayout.Space(1);
|
||||
@ -244,40 +255,21 @@ internal class UXButtonEditor : Editor
|
||||
|
||||
private void DrawBasicSettings()
|
||||
{
|
||||
if (m_Mode.enumValueIndex != m_ButtonMode)
|
||||
{
|
||||
if (m_ButtonMode == (int)ButtonModeType.Normal)
|
||||
{
|
||||
ResetEventProperty(m_OnValueChanged);
|
||||
m_UXGroup.objectReferenceValue = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetEventProperty(m_OnClick);
|
||||
}
|
||||
|
||||
m_ButtonMode = m_Mode.enumValueIndex;
|
||||
}
|
||||
|
||||
if (m_Mode.enumValueIndex == (int)ButtonModeType.Toggle)
|
||||
{
|
||||
GUILayoutHelper.DrawProperty(m_UXGroup, customSkin, "UXGroup");
|
||||
|
||||
UXGroup newGroup = (UXGroup)m_UXGroup.objectReferenceValue;
|
||||
if (newGroup != group)
|
||||
GUILayoutHelper.DrawProperty<UXGroup>(m_UXGroup, customSkin, "UXGroup", (oldValue, newValue) =>
|
||||
{
|
||||
UXButton self = target as UXButton;
|
||||
if (group != null)
|
||||
if (oldValue != null)
|
||||
{
|
||||
group.UnregisterButton(self);
|
||||
oldValue.UnregisterButton(self);
|
||||
}
|
||||
|
||||
group = newGroup;
|
||||
if (newGroup != null)
|
||||
if (newValue != null)
|
||||
{
|
||||
newGroup.RegisterButton(self);
|
||||
}
|
||||
newValue.RegisterButton(self);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ namespace AlicizaX.UI.RecyclerView
|
||||
|
||||
public GridLayoutManager()
|
||||
{
|
||||
this.unit = unit;
|
||||
unit = cellCount;
|
||||
}
|
||||
|
||||
public override Vector2 CalculateContentSize()
|
||||
|
||||
@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using AlicizaX.UI.Extension;
|
||||
using AlicizaX.UI.Extension.Utility;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.EventSystems;
|
||||
@ -138,7 +139,7 @@ public class UXButton : UIBehaviour, IButton,
|
||||
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
if (!CanProcess(eventData)) return;
|
||||
if (!CanProcess()) return;
|
||||
m_IsDown = true;
|
||||
SetState(SelectionState.Pressed);
|
||||
}
|
||||
@ -160,7 +161,7 @@ public class UXButton : UIBehaviour, IButton,
|
||||
|
||||
public void OnPointerEnter(PointerEventData eventData)
|
||||
{
|
||||
if (!CanProcess(eventData)) return;
|
||||
if (!CanProcess()) return;
|
||||
m_HasExitedWhileDown = false;
|
||||
if (m_IsDown) return;
|
||||
|
||||
@ -203,10 +204,9 @@ public class UXButton : UIBehaviour, IButton,
|
||||
|
||||
#region Logic
|
||||
|
||||
private bool CanProcess(PointerEventData eventData)
|
||||
private bool CanProcess()
|
||||
{
|
||||
return m_Interactable &&
|
||||
eventData.button == PointerEventData.InputButton.Left &&
|
||||
!(m_Mode == ButtonModeType.Toggle && Selected);
|
||||
}
|
||||
|
||||
@ -272,7 +272,19 @@ public class UXButton : UIBehaviour, IButton,
|
||||
|
||||
private void TweenColor(TransitionData data, Color color, bool instant)
|
||||
{
|
||||
data.targetGraphic.CrossFadeColor(color, instant ? 0f : data.colors.fadeDuration, true, true);
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
data.targetGraphic.CrossFadeColor(
|
||||
color,
|
||||
instant ? 0f : data.colors.fadeDuration,
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
data.targetGraphic.canvasRenderer.SetColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SwapSprite(TransitionData data, Sprite sprite)
|
||||
|
||||
@ -11,7 +11,6 @@ public class UXGroup : UIBehaviour
|
||||
[SerializeField] private List<UXButton> m_Buttons = new();
|
||||
|
||||
private UXButton _current;
|
||||
private readonly HashSet<UXButton> _registered = new();
|
||||
|
||||
public UnityEvent<UXButton> onSelectedChanged = new();
|
||||
|
||||
@ -29,18 +28,18 @@ public class UXGroup : UIBehaviour
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
foreach (var btn in _registered)
|
||||
foreach (var btn in m_Buttons)
|
||||
if (btn)
|
||||
btn.Selected = false;
|
||||
_registered.Clear();
|
||||
m_Buttons.Clear();
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
public void RegisterButton(UXButton button)
|
||||
{
|
||||
if (!button || !_registered.Add(button)) return;
|
||||
if (!m_Buttons.Contains(button)) m_Buttons.Add(button);
|
||||
if (!button) return;
|
||||
if (m_Buttons.Contains(button)) return;
|
||||
m_Buttons.Add(button);
|
||||
|
||||
if (button.Selected)
|
||||
{
|
||||
@ -54,7 +53,7 @@ public class UXGroup : UIBehaviour
|
||||
|
||||
public void UnregisterButton(UXButton button)
|
||||
{
|
||||
if (!button || !_registered.Remove(button)) return;
|
||||
if (!button) return;
|
||||
m_Buttons.Remove(button);
|
||||
if (_current == button)
|
||||
_current = null;
|
||||
|
||||
3
Runtime/Utility.meta
Normal file
3
Runtime/Utility.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2997e0ea45404b2bad0969025eb613a5
|
||||
timeCreated: 1760407867
|
||||
35
Runtime/Utility/SetPropertyUtility.cs
Normal file
35
Runtime/Utility/SetPropertyUtility.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.UI.Extension.Utility
|
||||
{
|
||||
internal static class SetPropertyUtility
|
||||
{
|
||||
public static bool SetColor(ref Color currentValue, Color newValue)
|
||||
{
|
||||
if (currentValue.r == newValue.r && currentValue.g == newValue.g && currentValue.b == newValue.b && currentValue.a == newValue.a)
|
||||
return false;
|
||||
|
||||
currentValue = newValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool SetStruct<T>(ref T currentValue, T newValue) where T : struct
|
||||
{
|
||||
if (EqualityComparer<T>.Default.Equals(currentValue, newValue))
|
||||
return false;
|
||||
|
||||
currentValue = newValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool SetClass<T>(ref T currentValue, T newValue) where T : class
|
||||
{
|
||||
if ((currentValue == null && newValue == null) || (currentValue != null && currentValue.Equals(newValue)))
|
||||
return false;
|
||||
|
||||
currentValue = newValue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Runtime/Utility/SetPropertyUtility.cs.meta
Normal file
3
Runtime/Utility/SetPropertyUtility.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: baab95df60ce49af96e3b0efcf82ed30
|
||||
timeCreated: 1760407873
|
||||
Loading…
Reference in New Issue
Block a user