From 839af110274ffe9498f4de468723ced56216b0f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=99=88=E6=80=9D=E6=B5=B7?= <1464576565@qq.com>
Date: Wed, 11 Mar 2026 15:23:44 +0800
Subject: [PATCH] 1
---
Editor/UX/Controller/UXControllerEditor.cs | 44 +-
.../UXControllerStateRecorderEditor.cs | 82 ++--
.../Property/CanvasGroupAlphaState.cs | 44 ++
.../Property/CanvasGroupInteractableState.cs | 49 ++
.../Property/GameObjectActiveState.cs | 45 ++
.../Property/GameObjectPropertyState.cs | 444 ------------------
.../Controller/Property/GraphicColorState.cs | 45 ++
.../Property/GraphicMaterialState.cs | 47 ++
.../Controller/Property/ImageSpriteState.cs | 47 ++
.../Controller/Property/TextColorState.cs | 61 +++
.../Controller/Property/TextContentState.cs | 49 ++
.../Property/TransformPositionState.cs | 44 ++
.../Property/TransformRotationState.cs | 44 ++
.../Property/TransformScaleState.cs | 44 ++
14 files changed, 582 insertions(+), 507 deletions(-)
create mode 100644 Runtime/UXComponent/Controller/Property/CanvasGroupAlphaState.cs
create mode 100644 Runtime/UXComponent/Controller/Property/CanvasGroupInteractableState.cs
create mode 100644 Runtime/UXComponent/Controller/Property/GameObjectActiveState.cs
delete mode 100644 Runtime/UXComponent/Controller/Property/GameObjectPropertyState.cs
create mode 100644 Runtime/UXComponent/Controller/Property/GraphicColorState.cs
create mode 100644 Runtime/UXComponent/Controller/Property/GraphicMaterialState.cs
create mode 100644 Runtime/UXComponent/Controller/Property/ImageSpriteState.cs
create mode 100644 Runtime/UXComponent/Controller/Property/TextColorState.cs
create mode 100644 Runtime/UXComponent/Controller/Property/TextContentState.cs
create mode 100644 Runtime/UXComponent/Controller/Property/TransformPositionState.cs
create mode 100644 Runtime/UXComponent/Controller/Property/TransformRotationState.cs
create mode 100644 Runtime/UXComponent/Controller/Property/TransformScaleState.cs
diff --git a/Editor/UX/Controller/UXControllerEditor.cs b/Editor/UX/Controller/UXControllerEditor.cs
index 0ac6aef..0ff483e 100644
--- a/Editor/UX/Controller/UXControllerEditor.cs
+++ b/Editor/UX/Controller/UXControllerEditor.cs
@@ -84,12 +84,12 @@ namespace AlicizaX.UI
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUILayout.BeginHorizontal();
- EditorGUILayout.LabelField("UX Controller", _headerStyle, GUILayout.Width(130));
- EditorGUILayout.LabelField($"Controllers: {_controllersProp.arraySize}", EditorStyles.miniLabel);
+ EditorGUILayout.LabelField("UX 控制器", _headerStyle, GUILayout.Width(130));
+ EditorGUILayout.LabelField($"控制器数量: {_controllersProp.arraySize}", EditorStyles.miniLabel);
GUILayout.FlexibleSpace();
- if (GUILayout.Button("+ Add Controller", GUILayout.Width(110)))
+ if (GUILayout.Button("+ 添加控制器", GUILayout.Width(110)))
{
AddNewController();
}
@@ -109,7 +109,7 @@ namespace AlicizaX.UI
EditorGUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
- _previewMode = EditorGUILayout.Toggle("Preview Mode", _previewMode);
+ _previewMode = EditorGUILayout.Toggle("预览模式", _previewMode);
if (EditorGUI.EndChangeCheck())
{
if (!_previewMode)
@@ -121,7 +121,7 @@ namespace AlicizaX.UI
if (_previewMode)
{
GUILayout.FlexibleSpace();
- if (GUILayout.Button("Reset All", GUILayout.Width(80)))
+ if (GUILayout.Button("重置全部", GUILayout.Width(80)))
{
ResetAllControllers(controller);
}
@@ -131,7 +131,7 @@ namespace AlicizaX.UI
if (_previewMode)
{
- EditorGUILayout.HelpBox("Preview mode active. Click state buttons to preview.", MessageType.Info);
+ EditorGUILayout.HelpBox("预览模式已激活。点击状态按钮进行预览。", MessageType.Info);
}
EditorGUILayout.EndVertical();
@@ -141,7 +141,7 @@ namespace AlicizaX.UI
{
EditorGUILayout.BeginHorizontal(_toolbarStyle);
- if (GUILayout.Button("Expand All", EditorStyles.toolbarButton, GUILayout.Width(70)))
+ if (GUILayout.Button("全部展开", EditorStyles.toolbarButton, GUILayout.Width(70)))
{
for (int i = 0; i < _controllersProp.arraySize; i++)
{
@@ -149,7 +149,7 @@ namespace AlicizaX.UI
}
}
- if (GUILayout.Button("Collapse All", EditorStyles.toolbarButton, GUILayout.Width(75)))
+ if (GUILayout.Button("全部折叠", EditorStyles.toolbarButton, GUILayout.Width(75)))
{
_controllerFoldouts.Clear();
}
@@ -163,7 +163,7 @@ namespace AlicizaX.UI
{
if (_controllersProp.arraySize == 0)
{
- EditorGUILayout.HelpBox("No controllers defined. Click '+ Add Controller' to create one.", MessageType.Info);
+ EditorGUILayout.HelpBox("未定义控制器。点击 '+ 添加控制器' 创建一个。", MessageType.Info);
return;
}
@@ -201,19 +201,19 @@ namespace AlicizaX.UI
// Name
EditorGUILayout.BeginHorizontal();
- EditorGUILayout.LabelField("Name", GUILayout.Width(70));
+ EditorGUILayout.LabelField("名称", GUILayout.Width(70));
nameProp.stringValue = EditorGUILayout.TextField(nameProp.stringValue);
EditorGUILayout.EndHorizontal();
// Length
EditorGUILayout.BeginHorizontal();
- EditorGUILayout.LabelField("Length", GUILayout.Width(70));
+ EditorGUILayout.LabelField("长度", GUILayout.Width(70));
lengthProp.intValue = Mathf.Max(1, EditorGUILayout.IntField(lengthProp.intValue));
EditorGUILayout.EndHorizontal();
// Description
EditorGUILayout.BeginHorizontal();
- EditorGUILayout.LabelField("Description", GUILayout.Width(70));
+ EditorGUILayout.LabelField("描述", GUILayout.Width(70));
descProp.stringValue = EditorGUILayout.TextField(descProp.stringValue);
EditorGUILayout.EndHorizontal();
@@ -260,8 +260,8 @@ namespace AlicizaX.UI
if (GUILayout.Button("×", EditorStyles.miniButtonRight, GUILayout.Width(25)))
{
- if (EditorUtility.DisplayDialog("Delete Controller",
- $"Delete controller '{nameProp.stringValue}'?", "Delete", "Cancel"))
+ if (EditorUtility.DisplayDialog("删除控制器",
+ $"删除控制器 '{nameProp.stringValue}'?", "删除", "取消"))
{
DeleteController(index);
}
@@ -273,7 +273,7 @@ namespace AlicizaX.UI
private void DrawControllerPreview(UXController controller, int controllerIndex, int length)
{
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
- EditorGUILayout.LabelField("Preview", EditorStyles.boldLabel);
+ EditorGUILayout.LabelField("预览", EditorStyles.boldLabel);
var handle = controller.GetControllerAt(controllerIndex);
if (handle != null)
@@ -281,7 +281,7 @@ namespace AlicizaX.UI
int currentIndex = handle.SelectedIndex;
EditorGUILayout.BeginHorizontal();
- EditorGUILayout.LabelField($"State: {currentIndex}", GUILayout.Width(60));
+ EditorGUILayout.LabelField($"状态: {currentIndex}", GUILayout.Width(60));
string[] options = new string[length];
for (int i = 0; i < length; i++)
@@ -309,14 +309,14 @@ namespace AlicizaX.UI
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUILayout.BeginHorizontal();
- _showRecorders = EditorGUILayout.Foldout(_showRecorders, $"State Recorders ({controller.Recorders.Count})", true);
+ _showRecorders = EditorGUILayout.Foldout(_showRecorders, $"状态记录器 ({controller.Recorders.Count})", true);
EditorGUILayout.EndHorizontal();
if (_showRecorders)
{
if (controller.Recorders.Count == 0)
{
- EditorGUILayout.HelpBox("No state recorders attached.", MessageType.Info);
+ EditorGUILayout.HelpBox("未附加状态记录器。", MessageType.Info);
}
else
{
@@ -347,9 +347,9 @@ namespace AlicizaX.UI
EditorGUILayout.ObjectField(recorder, typeof(UXControllerStateRecorder), true);
EditorGUI.EndDisabledGroup();
- EditorGUILayout.LabelField($"States: {recorder.StateEntries.Count}", GUILayout.Width(60));
+ EditorGUILayout.LabelField($"状态数: {recorder.StateEntries.Count}", GUILayout.Width(60));
- if (GUILayout.Button("Select", GUILayout.Width(60)))
+ if (GUILayout.Button("选择", GUILayout.Width(60)))
{
Selection.activeGameObject = recorder.gameObject;
}
@@ -373,7 +373,7 @@ namespace AlicizaX.UI
var newProp = _controllersProp.GetArrayElementAtIndex(index + 1);
var nameProp = newProp.FindPropertyRelative("_name");
- nameProp.stringValue += " Copy";
+ nameProp.stringValue += " 副本";
_controllerFoldouts[index + 1] = true;
}
@@ -385,7 +385,7 @@ namespace AlicizaX.UI
return;
}
- Undo.RecordObject(serializedObject.targetObject, "Delete Controller");
+ Undo.RecordObject(serializedObject.targetObject, "删除控制器");
_controllersProp.DeleteArrayElementAtIndex(index);
_controllerFoldouts.Remove(index);
diff --git a/Editor/UX/Controller/UXControllerStateRecorderEditor.cs b/Editor/UX/Controller/UXControllerStateRecorderEditor.cs
index f847143..f6f3e70 100644
--- a/Editor/UX/Controller/UXControllerStateRecorderEditor.cs
+++ b/Editor/UX/Controller/UXControllerStateRecorderEditor.cs
@@ -106,12 +106,12 @@ namespace AlicizaX.UI
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUILayout.BeginHorizontal();
- EditorGUILayout.LabelField("UX State Recorder", _headerStyle, GUILayout.Width(150));
+ EditorGUILayout.LabelField("UX 状态记录器", _headerStyle, GUILayout.Width(150));
EditorGUILayout.LabelField($"ID: {_id.intValue}", EditorStyles.miniLabel);
GUILayout.FlexibleSpace();
- if (GUILayout.Button("Refresh", EditorStyles.miniButtonLeft, GUILayout.Width(60)))
+ if (GUILayout.Button("刷新", EditorStyles.miniButtonLeft, GUILayout.Width(60)))
{
recorder.Initialize();
EditorUtility.SetDirty(recorder);
@@ -119,7 +119,7 @@ namespace AlicizaX.UI
Color oldColor = GUI.backgroundColor;
if (_compactMode) GUI.backgroundColor = Color.green;
- if (GUILayout.Button("Compact", EditorStyles.miniButtonRight, GUILayout.Width(60)))
+ if (GUILayout.Button("紧凑", EditorStyles.miniButtonRight, GUILayout.Width(60)))
{
_compactMode = !_compactMode;
_stateFoldouts.Clear();
@@ -151,14 +151,14 @@ namespace AlicizaX.UI
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUILayout.BeginHorizontal();
- _showControllerInfo = EditorGUILayout.Foldout(_showControllerInfo, "Controller Reference", true);
+ _showControllerInfo = EditorGUILayout.Foldout(_showControllerInfo, "控制器引用", true);
EditorGUILayout.EndHorizontal();
// Controller dropdown
var availableControllers = GetAvailableControllers(recorder);
EditorGUILayout.BeginHorizontal();
- EditorGUILayout.LabelField("Controller", GUILayout.Width(70));
+ EditorGUILayout.LabelField("控制器", GUILayout.Width(70));
if (availableControllers.Count > 0)
{
@@ -189,14 +189,14 @@ namespace AlicizaX.UI
}
}
- if (currentController != null && GUILayout.Button("Select", GUILayout.Width(60)))
+ if (currentController != null && GUILayout.Button("选择", GUILayout.Width(60)))
{
Selection.activeGameObject = currentController.gameObject;
}
}
else
{
- EditorGUILayout.LabelField("(No controllers found in parents)", EditorStyles.miniLabel);
+ EditorGUILayout.LabelField("(在父对象中未找到控制器)", EditorStyles.miniLabel);
}
EditorGUILayout.EndHorizontal();
@@ -207,7 +207,7 @@ namespace AlicizaX.UI
UXController ctl = _controller.objectReferenceValue as UXController;
EditorGUI.indentLevel++;
- EditorGUILayout.LabelField($"Controllers: {ctl.ControllerCount}", EditorStyles.miniLabel);
+ EditorGUILayout.LabelField($"控制器数量: {ctl.ControllerCount}", EditorStyles.miniLabel);
for (int i = 0; i < ctl.ControllerCount; i++)
{
@@ -215,7 +215,7 @@ namespace AlicizaX.UI
if (handle != null)
{
string desc = string.IsNullOrEmpty(handle.Description) ? "" : $" - {handle.Description}";
- EditorGUILayout.LabelField($" [{i}] {handle.Name} (Length: {handle.Length}){desc}", EditorStyles.miniLabel);
+ EditorGUILayout.LabelField($" [{i}] {handle.Name} (长度: {handle.Length}){desc}", EditorStyles.miniLabel);
}
}
EditorGUI.indentLevel--;
@@ -223,7 +223,7 @@ namespace AlicizaX.UI
if (_controller.objectReferenceValue == null)
{
- EditorGUILayout.HelpBox("No controller assigned. Add UXController to parent GameObject.", MessageType.Warning);
+ EditorGUILayout.HelpBox("未分配控制器。请在父对象上添加 UXController。", MessageType.Warning);
}
EditorGUILayout.EndVertical();
@@ -233,23 +233,23 @@ namespace AlicizaX.UI
{
EditorGUILayout.BeginHorizontal(_toolbarStyle);
- if (GUILayout.Button("+ Add State", EditorStyles.toolbarButton, GUILayout.Width(100)))
+ if (GUILayout.Button("+ 添加状态", EditorStyles.toolbarButton, GUILayout.Width(100)))
{
ShowAddStateMenu();
}
EditorGUI.BeginDisabledGroup(_stateEntriesProp.arraySize == 0);
- if (GUILayout.Button("Clear All", EditorStyles.toolbarButton, GUILayout.Width(70)))
+ if (GUILayout.Button("清空全部", EditorStyles.toolbarButton, GUILayout.Width(70)))
{
- if (EditorUtility.DisplayDialog("Clear All States",
- "Remove all states?", "Clear", "Cancel"))
+ if (EditorUtility.DisplayDialog("清空所有状态",
+ "移除所有状态?", "清空", "取消"))
{
ClearAllStates();
}
}
EditorGUI.EndDisabledGroup();
- if (GUILayout.Button("Expand All", EditorStyles.toolbarButton, GUILayout.Width(70)))
+ if (GUILayout.Button("全部展开", EditorStyles.toolbarButton, GUILayout.Width(70)))
{
for (int i = 0; i < _stateEntriesProp.arraySize; i++)
{
@@ -257,14 +257,14 @@ namespace AlicizaX.UI
}
}
- if (GUILayout.Button("Collapse All", EditorStyles.toolbarButton, GUILayout.Width(75)))
+ if (GUILayout.Button("全部折叠", EditorStyles.toolbarButton, GUILayout.Width(75)))
{
_stateFoldouts.Clear();
}
GUILayout.FlexibleSpace();
- EditorGUILayout.LabelField($"States: {_stateEntriesProp.arraySize}", EditorStyles.miniLabel, GUILayout.Width(70));
+ EditorGUILayout.LabelField($"状态数: {_stateEntriesProp.arraySize}", EditorStyles.miniLabel, GUILayout.Width(70));
EditorGUILayout.EndHorizontal();
}
@@ -273,7 +273,7 @@ namespace AlicizaX.UI
{
if (_stateEntriesProp.arraySize == 0)
{
- EditorGUILayout.HelpBox("No states defined. Click '+ Add State' to begin.", MessageType.Info);
+ EditorGUILayout.HelpBox("未定义状态。点击 '+ 添加状态' 开始。", MessageType.Info);
return;
}
@@ -336,15 +336,15 @@ namespace AlicizaX.UI
try
{
string bindingText = string.IsNullOrEmpty(controllerNameProp.stringValue)
- ? "Not Bound"
- : $"Bound to: {controllerNameProp.stringValue}[{controllerIndexProp.intValue}]";
+ ? "未绑定"
+ : $"绑定到: {controllerNameProp.stringValue}[{controllerIndexProp.intValue}]";
EditorGUILayout.LabelField(bindingText, EditorStyles.miniLabel);
// 在紧凑模式下也允许快速修改索引
if (!string.IsNullOrEmpty(controllerNameProp.stringValue))
{
EditorGUILayout.BeginHorizontal();
- EditorGUILayout.LabelField("Index", GUILayout.Width(50));
+ EditorGUILayout.LabelField("索引", GUILayout.Width(50));
int ctrlLen = GetSelectedControllerLength(recorder, controllerNameProp.stringValue);
if (ctrlLen <= 0) ctrlLen = 1;
@@ -363,7 +363,7 @@ namespace AlicizaX.UI
}
catch (ObjectDisposedException)
{
- EditorGUILayout.LabelField("Binding: (refreshing...)", EditorStyles.miniLabel);
+ EditorGUILayout.LabelField("绑定: (刷新中...)", EditorStyles.miniLabel);
}
EditorGUI.indentLevel--;
}
@@ -382,10 +382,10 @@ namespace AlicizaX.UI
if (stateInstance != null)
{
EditorGUILayout.BeginHorizontal();
- EditorGUILayout.LabelField("Properties", EditorStyles.boldLabel);
+ EditorGUILayout.LabelField("属性", EditorStyles.boldLabel);
// Set to Current Value button
- if (GUILayout.Button("Set to Current", GUILayout.Width(110)))
+ if (GUILayout.Button("设为当前值", GUILayout.Width(110)))
{
SetStateToCurrentValue(recorder, stateInstance, stateProp);
}
@@ -406,7 +406,7 @@ namespace AlicizaX.UI
// Validation warning
if (!isValid)
{
- EditorGUILayout.HelpBox("State validation failed. Check required components.", MessageType.Error);
+ EditorGUILayout.HelpBox("状态验证失败。请检查所需组件。", MessageType.Error);
}
EditorGUI.indentLevel--;
@@ -454,18 +454,18 @@ namespace AlicizaX.UI
// Safety check: ensure properties are valid
if (controllerNameProp == null || controllerIndexProp == null)
{
- EditorGUILayout.HelpBox("Binding properties are invalid. Try refreshing.", MessageType.Warning);
+ EditorGUILayout.HelpBox("绑定属性无效。请尝试刷新。", MessageType.Warning);
return;
}
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
- EditorGUILayout.LabelField("Binding", EditorStyles.boldLabel);
+ EditorGUILayout.LabelField("绑定", EditorStyles.boldLabel);
var controllerNames = GetControllerNamesForRecorder(recorder);
// Controller dropdown
EditorGUILayout.BeginHorizontal();
- EditorGUILayout.LabelField("Controller", GUILayout.Width(70));
+ EditorGUILayout.LabelField("控制器", GUILayout.Width(70));
if (controllerNames.Count > 0)
{
@@ -494,7 +494,7 @@ namespace AlicizaX.UI
}
else
{
- EditorGUILayout.LabelField("(No controllers available)", EditorStyles.miniLabel);
+ EditorGUILayout.LabelField("(无可用控制器)", EditorStyles.miniLabel);
}
EditorGUILayout.EndHorizontal();
@@ -502,7 +502,7 @@ namespace AlicizaX.UI
if (controllerNames.Count > 0 && !string.IsNullOrEmpty(controllerNameProp.stringValue))
{
EditorGUILayout.BeginHorizontal();
- EditorGUILayout.LabelField("Index", GUILayout.Width(70));
+ EditorGUILayout.LabelField("索引", GUILayout.Width(70));
int ctrlLen = GetSelectedControllerLength(recorder, controllerNameProp.stringValue);
if (ctrlLen <= 0) ctrlLen = 1;
@@ -523,7 +523,7 @@ namespace AlicizaX.UI
// Preview button
if (_controller.objectReferenceValue != null && !Application.isPlaying)
{
- if (GUILayout.Button("Preview", GUILayout.Width(60)))
+ if (GUILayout.Button("预览", GUILayout.Width(60)))
{
PreviewState(controllerNameProp.stringValue, controllerIndexProp.intValue);
}
@@ -544,15 +544,15 @@ namespace AlicizaX.UI
GUI.backgroundColor = oldColor;
EditorGUILayout.BeginHorizontal();
- EditorGUILayout.LabelField($"[{index}] Invalid State", EditorStyles.boldLabel);
+ EditorGUILayout.LabelField($"[{index}] 无效状态", EditorStyles.boldLabel);
- if (GUILayout.Button("Remove", GUILayout.Width(60)))
+ if (GUILayout.Button("移除", GUILayout.Width(60)))
{
DeleteStateAtIndex(index);
}
EditorGUILayout.EndHorizontal();
- EditorGUILayout.HelpBox("State data is corrupted. Remove and re-add.", MessageType.Error);
+ EditorGUILayout.HelpBox("状态数据已损坏。请移除并重新添加。", MessageType.Error);
EditorGUILayout.EndVertical();
}
@@ -565,7 +565,7 @@ namespace AlicizaX.UI
return;
}
- Undo.RecordObject(serializedObject.targetObject, "Delete State");
+ Undo.RecordObject(serializedObject.targetObject, "删除状态");
// Get the entry before deleting
var entryProp = _stateEntriesProp.GetArrayElementAtIndex(index);
@@ -608,7 +608,7 @@ namespace AlicizaX.UI
private void ClearAllStates()
{
- Undo.RecordObject(serializedObject.targetObject, "Clear All States");
+ Undo.RecordObject(serializedObject.targetObject, "清空所有状态");
// Clear all managed references first
for (int i = _stateEntriesProp.arraySize - 1; i >= 0; i--)
@@ -651,7 +651,7 @@ namespace AlicizaX.UI
return;
}
- Undo.RecordObject(serializedObject.targetObject, "Duplicate State");
+ Undo.RecordObject(serializedObject.targetObject, "复制状态");
_stateEntriesProp.InsertArrayElementAtIndex(index);
@@ -685,7 +685,7 @@ namespace AlicizaX.UI
return;
}
- Undo.RecordObject(serializedObject.targetObject, "Move State Up");
+ Undo.RecordObject(serializedObject.targetObject, "上移状态");
_stateEntriesProp.MoveArrayElement(index, index - 1);
@@ -711,7 +711,7 @@ namespace AlicizaX.UI
return;
}
- Undo.RecordObject(serializedObject.targetObject, "Move State Down");
+ Undo.RecordObject(serializedObject.targetObject, "下移状态");
_stateEntriesProp.MoveArrayElement(index, index + 1);
@@ -754,7 +754,7 @@ namespace AlicizaX.UI
{
if (type == null) return;
- Undo.RecordObject(serializedObject.targetObject, "Add Controller State");
+ Undo.RecordObject(serializedObject.targetObject, "添加控制器状态");
serializedObject.Update();
int idx = _stateEntriesProp.arraySize;
@@ -941,7 +941,7 @@ namespace AlicizaX.UI
{
if (recorder == null || state == null) return;
- Undo.RecordObject(recorder, "Set State to Current Value");
+ Undo.RecordObject(recorder, "设置状态为当前值");
// Use reflection to set current values based on state type
var stateType = state.GetType();
diff --git a/Runtime/UXComponent/Controller/Property/CanvasGroupAlphaState.cs b/Runtime/UXComponent/Controller/Property/CanvasGroupAlphaState.cs
new file mode 100644
index 0000000..729908f
--- /dev/null
+++ b/Runtime/UXComponent/Controller/Property/CanvasGroupAlphaState.cs
@@ -0,0 +1,44 @@
+using System;
+using UnityEngine;
+
+namespace AlicizaX.UI
+{
+ ///
+ /// CanvasGroup 透明度状态控制
+ /// 控制 CanvasGroup 的 Alpha 值
+ ///
+ [Serializable]
+ [ControlerStateName("CanvasGroup/Alpha")]
+ [ControlerStateAttachType(true)]
+ public class CanvasGroupAlphaState : ControllerStateBase
+ {
+ [SerializeField] [Range(0f, 1f)] private float _alpha = 1f;
+ [HideInInspector] [SerializeField] private float _defaultAlpha;
+
+ public override void Init(UXControllerStateRecorder recorder)
+ {
+ if (recorder != null && recorder.TryGetComponent(out var canvasGroup))
+ {
+ _defaultAlpha = canvasGroup.alpha;
+ }
+ }
+
+ public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
+ {
+ if (recorder != null && recorder.TryGetComponent(out var canvasGroup))
+ {
+ canvasGroup.alpha = (entryIndex == selectionIndex) ? _alpha : _defaultAlpha;
+ }
+ }
+
+ public override bool Valid(UXControllerStateRecorder recorder)
+ {
+ return recorder != null && recorder.GetComponent() != null;
+ }
+
+ public override string GetDescription()
+ {
+ return $"匹配时: 透明度={_alpha:F2}, 默认={_defaultAlpha:F2}";
+ }
+ }
+}
diff --git a/Runtime/UXComponent/Controller/Property/CanvasGroupInteractableState.cs b/Runtime/UXComponent/Controller/Property/CanvasGroupInteractableState.cs
new file mode 100644
index 0000000..3b3b42c
--- /dev/null
+++ b/Runtime/UXComponent/Controller/Property/CanvasGroupInteractableState.cs
@@ -0,0 +1,49 @@
+using System;
+using UnityEngine;
+
+namespace AlicizaX.UI
+{
+ ///
+ /// CanvasGroup 交互状态控制
+ /// 控制 CanvasGroup 的可交互性和射线检测
+ ///
+ [Serializable]
+ [ControlerStateName("CanvasGroup/Interactable")]
+ [ControlerStateAttachType(true)]
+ public class CanvasGroupInteractableState : ControllerStateBase
+ {
+ [SerializeField] private bool _interactable = true;
+ [SerializeField] private bool _blocksRaycasts = true;
+ [HideInInspector] [SerializeField] private bool _defaultInteractable = true;
+ [HideInInspector] [SerializeField] private bool _defaultBlocksRaycasts = true;
+
+ public override void Init(UXControllerStateRecorder recorder)
+ {
+ if (recorder != null && recorder.TryGetComponent(out var canvasGroup))
+ {
+ _defaultInteractable = canvasGroup.interactable;
+ _defaultBlocksRaycasts = canvasGroup.blocksRaycasts;
+ }
+ }
+
+ public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
+ {
+ if (recorder != null && recorder.TryGetComponent(out var canvasGroup))
+ {
+ bool isActive = (entryIndex == selectionIndex);
+ canvasGroup.interactable = isActive ? _interactable : _defaultInteractable;
+ canvasGroup.blocksRaycasts = isActive ? _blocksRaycasts : _defaultBlocksRaycasts;
+ }
+ }
+
+ public override bool Valid(UXControllerStateRecorder recorder)
+ {
+ return recorder != null && recorder.GetComponent() != null;
+ }
+
+ public override string GetDescription()
+ {
+ return $"匹配时: 可交互={_interactable}, 射线检测={_blocksRaycasts}";
+ }
+ }
+}
diff --git a/Runtime/UXComponent/Controller/Property/GameObjectActiveState.cs b/Runtime/UXComponent/Controller/Property/GameObjectActiveState.cs
new file mode 100644
index 0000000..202da84
--- /dev/null
+++ b/Runtime/UXComponent/Controller/Property/GameObjectActiveState.cs
@@ -0,0 +1,45 @@
+using System;
+using UnityEngine;
+
+namespace AlicizaX.UI
+{
+ ///
+ /// GameObject 激活状态控制
+ /// 控制对象的显示/隐藏
+ ///
+ [Serializable]
+ [ControlerStateName("GameObject/Active")]
+ [ControlerStateAttachType(true)]
+ public class GameObjectActiveState : ControllerStateBase
+ {
+ [SerializeField] private bool _active = true;
+ [HideInInspector] [SerializeField] private bool _defaultActive = true;
+
+ public override void Init(UXControllerStateRecorder recorder)
+ {
+ if (recorder != null && recorder.gameObject != null)
+ {
+ _defaultActive = recorder.gameObject.activeSelf;
+ }
+ }
+
+ public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
+ {
+ if (recorder != null && recorder.gameObject != null)
+ {
+ bool shouldBeActive = (entryIndex == selectionIndex) ? _active : _defaultActive;
+ recorder.gameObject.SetActive(shouldBeActive);
+ }
+ }
+
+ public override bool Valid(UXControllerStateRecorder recorder)
+ {
+ return recorder != null && recorder.gameObject != null;
+ }
+
+ public override string GetDescription()
+ {
+ return $"匹配时: {(_active ? "显示" : "隐藏")}, 默认: {(_defaultActive ? "显示" : "隐藏")}";
+ }
+ }
+}
diff --git a/Runtime/UXComponent/Controller/Property/GameObjectPropertyState.cs b/Runtime/UXComponent/Controller/Property/GameObjectPropertyState.cs
deleted file mode 100644
index c823160..0000000
--- a/Runtime/UXComponent/Controller/Property/GameObjectPropertyState.cs
+++ /dev/null
@@ -1,444 +0,0 @@
-using System;
-using UnityEngine;
-using UnityEngine.UI;
-using TMPro;
-
-namespace AlicizaX.UI
-{
- #region GameObject States
-
- [Serializable]
- [ControlerStateName("GameObject/Active")]
- [ControlerStateAttachType(true)]
- public class GameObjectActiveState : ControllerStateBase
- {
- [SerializeField] private bool _active = true;
- [HideInInspector] [SerializeField] private bool _defaultActive = true;
-
- public override void Init(UXControllerStateRecorder recorder)
- {
- if (recorder != null && recorder.gameObject != null)
- {
- _defaultActive = recorder.gameObject.activeSelf;
- }
- }
-
- public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
- {
- if (recorder != null && recorder.gameObject != null)
- {
- bool shouldBeActive = (entryIndex == selectionIndex) ? _active : _defaultActive;
- recorder.gameObject.SetActive(shouldBeActive);
- }
- }
-
- public override bool Valid(UXControllerStateRecorder recorder)
- {
- return recorder != null && recorder.gameObject != null;
- }
-
- public override string GetDescription()
- {
- return $"When Matched: {(_active ? "Show" : "Hide")}, Default: {(_defaultActive ? "Show" : "Hide")}";
- }
- }
-
- #endregion
-
- #region Transform States
-
- [Serializable]
- [ControlerStateName("Transform/Position")]
- [ControlerStateAttachType(true)]
- public class TransformPositionState : ControllerStateBase
- {
- [SerializeField] private Vector2 _position;
- [HideInInspector] [SerializeField] private Vector2 _defaultPosition;
-
- public override void Init(UXControllerStateRecorder recorder)
- {
- if (recorder != null && recorder.TryGetComponent(out var rect))
- {
- _defaultPosition = rect.anchoredPosition;
- }
- }
-
- public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
- {
- if (recorder != null && recorder.TryGetComponent(out var rect))
- {
- rect.anchoredPosition = (entryIndex == selectionIndex) ? _position : _defaultPosition;
- }
- }
-
- public override bool Valid(UXControllerStateRecorder recorder)
- {
- return recorder != null && recorder.GetComponent() != null;
- }
-
- public override string GetDescription()
- {
- return $"When Matched: Position={_position}, Default={_defaultPosition}";
- }
- }
-
- [Serializable]
- [ControlerStateName("Transform/Scale")]
- [ControlerStateAttachType(true)]
- public class TransformScaleState : ControllerStateBase
- {
- [SerializeField] private Vector3 _scale = Vector3.one;
- [HideInInspector] [SerializeField] private Vector3 _defaultScale;
-
- public override void Init(UXControllerStateRecorder recorder)
- {
- if (recorder != null && recorder.transform != null)
- {
- _defaultScale = recorder.transform.localScale;
- }
- }
-
- public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
- {
- if (recorder != null && recorder.transform != null)
- {
- recorder.transform.localScale = (entryIndex == selectionIndex) ? _scale : _defaultScale;
- }
- }
-
- public override bool Valid(UXControllerStateRecorder recorder)
- {
- return recorder != null && recorder.transform != null;
- }
-
- public override string GetDescription()
- {
- return $"When Matched: Scale={_scale}, Default={_defaultScale}";
- }
- }
-
- [Serializable]
- [ControlerStateName("Transform/Rotation")]
- [ControlerStateAttachType(true)]
- public class TransformRotationState : ControllerStateBase
- {
- [SerializeField] private Vector3 _rotation;
- [HideInInspector] [SerializeField] private Vector3 _defaultRotation;
-
- public override void Init(UXControllerStateRecorder recorder)
- {
- if (recorder != null && recorder.transform != null)
- {
- _defaultRotation = recorder.transform.localEulerAngles;
- }
- }
-
- public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
- {
- if (recorder != null && recorder.transform != null)
- {
- recorder.transform.localEulerAngles = (entryIndex == selectionIndex) ? _rotation : _defaultRotation;
- }
- }
-
- public override bool Valid(UXControllerStateRecorder recorder)
- {
- return recorder != null && recorder.transform != null;
- }
-
- public override string GetDescription()
- {
- return $"When Matched: Rotation={_rotation}, Default={_defaultRotation}";
- }
- }
-
- #endregion
-
- #region Graphic States
-
- [Serializable]
- [ControlerStateName("Graphic/Color")]
- [ControlerStateAttachType(true)]
- public class GraphicColorState : ControllerStateBase
- {
- [SerializeField] private Color _color = Color.white;
- [HideInInspector] [SerializeField] private Color _defaultColor;
-
- public override void Init(UXControllerStateRecorder recorder)
- {
- if (recorder != null && recorder.TryGetComponent(out var graphic))
- {
- _defaultColor = graphic.color;
- }
- }
-
- public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
- {
- if (recorder != null && recorder.TryGetComponent(out var graphic))
- {
- graphic.color = (entryIndex == selectionIndex) ? _color : _defaultColor;
- }
- }
-
- public override bool Valid(UXControllerStateRecorder recorder)
- {
- return recorder != null && recorder.GetComponent() != null;
- }
-
- public override string GetDescription()
- {
- return $"When Matched: Color={_color}, Default={_defaultColor}";
- }
- }
-
- [Serializable]
- [ControlerStateName("Graphic/Material")]
- [ControlerStateAttachType(true)]
- public class GraphicMaterialState : ControllerStateBase
- {
- [SerializeField] private Material _material;
- [HideInInspector] [SerializeField] private Material _defaultMaterial;
-
- public override void Init(UXControllerStateRecorder recorder)
- {
- if (recorder != null && recorder.TryGetComponent(out var graphic))
- {
- _defaultMaterial = graphic.material;
- }
- }
-
- public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
- {
- if (recorder != null && recorder.TryGetComponent(out var graphic))
- {
- graphic.material = (entryIndex == selectionIndex) ? _material : _defaultMaterial;
- }
- }
-
- public override bool Valid(UXControllerStateRecorder recorder)
- {
- return recorder != null && recorder.GetComponent() != null;
- }
-
- public override string GetDescription()
- {
- string matched = _material != null ? _material.name : "None";
- string defaultVal = _defaultMaterial != null ? _defaultMaterial.name : "None";
- return $"When Matched: {matched}, Default: {defaultVal}";
- }
- }
-
- #endregion
-
- #region Image States
-
- [Serializable]
- [ControlerStateName("Image/Sprite")]
- [ControlerStateAttachType(true)]
- public class ImageSpriteState : ControllerStateBase
- {
- [SerializeField] private Sprite _sprite;
- [HideInInspector] [SerializeField] private Sprite _defaultSprite;
-
- public override void Init(UXControllerStateRecorder recorder)
- {
- if (recorder != null && recorder.TryGetComponent(out var image))
- {
- _defaultSprite = image.sprite;
- }
- }
-
- public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
- {
- if (recorder != null && recorder.TryGetComponent(out var image))
- {
- image.sprite = (entryIndex == selectionIndex) ? _sprite : _defaultSprite;
- }
- }
-
- public override bool Valid(UXControllerStateRecorder recorder)
- {
- return recorder != null && recorder.GetComponent() != null;
- }
-
- public override string GetDescription()
- {
- string matched = _sprite != null ? _sprite.name : "None";
- string defaultVal = _defaultSprite != null ? _defaultSprite.name : "None";
- return $"When Matched: {matched}, Default: {defaultVal}";
- }
- }
-
- #endregion
-
- #region Text States
-
- [Serializable]
- [ControlerStateName("Text/Content")]
- [ControlerStateAttachType(true)]
- public class TextContentState : ControllerStateBase
- {
- [SerializeField] [TextArea(3, 10)] private string _text = "";
-
- public override void Init(UXControllerStateRecorder recorder)
- {
- }
-
- public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
- {
- if (recorder == null || entryIndex != selectionIndex) return;
-
- if (recorder.TryGetComponent(out var text))
- {
- text.text = _text;
- }
- else if (recorder.TryGetComponent(out var tmp))
- {
- tmp.text = _text;
- }
- }
-
- public override bool Valid(UXControllerStateRecorder recorder)
- {
- return recorder != null &&
- (recorder.GetComponent() != null || recorder.GetComponent() != null);
- }
-
- public override string GetDescription()
- {
- string preview = _text.Length > 30 ? _text.Substring(0, 30) + "..." : _text;
- return $"When Matched: \"{preview}\"";
- }
- }
-
- [Serializable]
- [ControlerStateName("Text/Color")]
- [ControlerStateAttachType(true)]
- public class TextColorState : ControllerStateBase
- {
- [SerializeField] private Color _color = Color.white;
- [HideInInspector] [SerializeField] private Color _defaultColor;
-
- public override void Init(UXControllerStateRecorder recorder)
- {
- if (recorder == null) return;
-
- if (recorder.TryGetComponent(out var text))
- {
- _defaultColor = text.color;
- }
- else if (recorder.TryGetComponent(out var tmp))
- {
- _defaultColor = tmp.color;
- }
- }
-
- public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
- {
- if (recorder == null) return;
-
- Color targetColor = (entryIndex == selectionIndex) ? _color : _defaultColor;
-
- if (recorder.TryGetComponent(out var text))
- {
- text.color = targetColor;
- }
- else if (recorder.TryGetComponent(out var tmp))
- {
- tmp.color = targetColor;
- }
- }
-
- public override bool Valid(UXControllerStateRecorder recorder)
- {
- return recorder != null &&
- (recorder.GetComponent() != null || recorder.GetComponent() != null);
- }
-
- public override string GetDescription()
- {
- return $"When Matched: Color={_color}, Default={_defaultColor}";
- }
- }
-
- #endregion
-
- #region CanvasGroup States
-
- [Serializable]
- [ControlerStateName("CanvasGroup/Alpha")]
- [ControlerStateAttachType(true)]
- public class CanvasGroupAlphaState : ControllerStateBase
- {
- [SerializeField] [Range(0f, 1f)] private float _alpha = 1f;
- [HideInInspector] [SerializeField] private float _defaultAlpha;
-
- public override void Init(UXControllerStateRecorder recorder)
- {
- if (recorder != null && recorder.TryGetComponent(out var canvasGroup))
- {
- _defaultAlpha = canvasGroup.alpha;
- }
- }
-
- public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
- {
- if (recorder != null && recorder.TryGetComponent(out var canvasGroup))
- {
- canvasGroup.alpha = (entryIndex == selectionIndex) ? _alpha : _defaultAlpha;
- }
- }
-
- public override bool Valid(UXControllerStateRecorder recorder)
- {
- return recorder != null && recorder.GetComponent() != null;
- }
-
- public override string GetDescription()
- {
- return $"When Matched: Alpha={_alpha:F2}, Default={_defaultAlpha:F2}";
- }
- }
-
- [Serializable]
- [ControlerStateName("CanvasGroup/Interactable")]
- [ControlerStateAttachType(true)]
- public class CanvasGroupInteractableState : ControllerStateBase
- {
- [SerializeField] private bool _interactable = true;
- [SerializeField] private bool _blocksRaycasts = true;
- [HideInInspector] [SerializeField] private bool _defaultInteractable = true;
- [HideInInspector] [SerializeField] private bool _defaultBlocksRaycasts = true;
-
- public override void Init(UXControllerStateRecorder recorder)
- {
- if (recorder != null && recorder.TryGetComponent(out var canvasGroup))
- {
- _defaultInteractable = canvasGroup.interactable;
- _defaultBlocksRaycasts = canvasGroup.blocksRaycasts;
- }
- }
-
- public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
- {
- if (recorder != null && recorder.TryGetComponent(out var canvasGroup))
- {
- bool isActive = (entryIndex == selectionIndex);
- canvasGroup.interactable = isActive ? _interactable : _defaultInteractable;
- canvasGroup.blocksRaycasts = isActive ? _blocksRaycasts : _defaultBlocksRaycasts;
- }
- }
-
- public override bool Valid(UXControllerStateRecorder recorder)
- {
- return recorder != null && recorder.GetComponent() != null;
- }
-
- public override string GetDescription()
- {
- return $"When Matched: Interactable={_interactable}, Raycast={_blocksRaycasts}";
- }
- }
-
- #endregion
-}
diff --git a/Runtime/UXComponent/Controller/Property/GraphicColorState.cs b/Runtime/UXComponent/Controller/Property/GraphicColorState.cs
new file mode 100644
index 0000000..920b6de
--- /dev/null
+++ b/Runtime/UXComponent/Controller/Property/GraphicColorState.cs
@@ -0,0 +1,45 @@
+using System;
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace AlicizaX.UI
+{
+ ///
+ /// Graphic 颜色状态控制
+ /// 控制 UI 图形组件的颜色
+ ///
+ [Serializable]
+ [ControlerStateName("Graphic/Color")]
+ [ControlerStateAttachType(true)]
+ public class GraphicColorState : ControllerStateBase
+ {
+ [SerializeField] private Color _color = Color.white;
+ [HideInInspector] [SerializeField] private Color _defaultColor;
+
+ public override void Init(UXControllerStateRecorder recorder)
+ {
+ if (recorder != null && recorder.TryGetComponent(out var graphic))
+ {
+ _defaultColor = graphic.color;
+ }
+ }
+
+ public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
+ {
+ if (recorder != null && recorder.TryGetComponent(out var graphic))
+ {
+ graphic.color = (entryIndex == selectionIndex) ? _color : _defaultColor;
+ }
+ }
+
+ public override bool Valid(UXControllerStateRecorder recorder)
+ {
+ return recorder != null && recorder.GetComponent() != null;
+ }
+
+ public override string GetDescription()
+ {
+ return $"匹配时: 颜色={_color}, 默认={_defaultColor}";
+ }
+ }
+}
diff --git a/Runtime/UXComponent/Controller/Property/GraphicMaterialState.cs b/Runtime/UXComponent/Controller/Property/GraphicMaterialState.cs
new file mode 100644
index 0000000..5080296
--- /dev/null
+++ b/Runtime/UXComponent/Controller/Property/GraphicMaterialState.cs
@@ -0,0 +1,47 @@
+using System;
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace AlicizaX.UI
+{
+ ///
+ /// Graphic 材质状态控制
+ /// 控制 UI 图形组件的材质
+ ///
+ [Serializable]
+ [ControlerStateName("Graphic/Material")]
+ [ControlerStateAttachType(true)]
+ public class GraphicMaterialState : ControllerStateBase
+ {
+ [SerializeField] private Material _material;
+ [HideInInspector] [SerializeField] private Material _defaultMaterial;
+
+ public override void Init(UXControllerStateRecorder recorder)
+ {
+ if (recorder != null && recorder.TryGetComponent(out var graphic))
+ {
+ _defaultMaterial = graphic.material;
+ }
+ }
+
+ public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
+ {
+ if (recorder != null && recorder.TryGetComponent(out var graphic))
+ {
+ graphic.material = (entryIndex == selectionIndex) ? _material : _defaultMaterial;
+ }
+ }
+
+ public override bool Valid(UXControllerStateRecorder recorder)
+ {
+ return recorder != null && recorder.GetComponent() != null;
+ }
+
+ public override string GetDescription()
+ {
+ string matched = _material != null ? _material.name : "无";
+ string defaultVal = _defaultMaterial != null ? _defaultMaterial.name : "无";
+ return $"匹配时: {matched}, 默认: {defaultVal}";
+ }
+ }
+}
diff --git a/Runtime/UXComponent/Controller/Property/ImageSpriteState.cs b/Runtime/UXComponent/Controller/Property/ImageSpriteState.cs
new file mode 100644
index 0000000..e413b95
--- /dev/null
+++ b/Runtime/UXComponent/Controller/Property/ImageSpriteState.cs
@@ -0,0 +1,47 @@
+using System;
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace AlicizaX.UI
+{
+ ///
+ /// Image 精灵图状态控制
+ /// 控制 Image 组件的 Sprite
+ ///
+ [Serializable]
+ [ControlerStateName("Image/Sprite")]
+ [ControlerStateAttachType(true)]
+ public class ImageSpriteState : ControllerStateBase
+ {
+ [SerializeField] private Sprite _sprite;
+ [HideInInspector] [SerializeField] private Sprite _defaultSprite;
+
+ public override void Init(UXControllerStateRecorder recorder)
+ {
+ if (recorder != null && recorder.TryGetComponent(out var image))
+ {
+ _defaultSprite = image.sprite;
+ }
+ }
+
+ public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
+ {
+ if (recorder != null && recorder.TryGetComponent(out var image))
+ {
+ image.sprite = (entryIndex == selectionIndex) ? _sprite : _defaultSprite;
+ }
+ }
+
+ public override bool Valid(UXControllerStateRecorder recorder)
+ {
+ return recorder != null && recorder.GetComponent() != null;
+ }
+
+ public override string GetDescription()
+ {
+ string matched = _sprite != null ? _sprite.name : "无";
+ string defaultVal = _defaultSprite != null ? _defaultSprite.name : "无";
+ return $"匹配时: {matched}, 默认: {defaultVal}";
+ }
+ }
+}
diff --git a/Runtime/UXComponent/Controller/Property/TextColorState.cs b/Runtime/UXComponent/Controller/Property/TextColorState.cs
new file mode 100644
index 0000000..88e72c6
--- /dev/null
+++ b/Runtime/UXComponent/Controller/Property/TextColorState.cs
@@ -0,0 +1,61 @@
+using System;
+using UnityEngine;
+using UnityEngine.UI;
+using TMPro;
+
+namespace AlicizaX.UI
+{
+ ///
+ /// Text 颜色状态控制
+ /// 控制 Text 或 TextMeshProUGUI 的文本颜色
+ ///
+ [Serializable]
+ [ControlerStateName("Text/Color")]
+ [ControlerStateAttachType(true)]
+ public class TextColorState : ControllerStateBase
+ {
+ [SerializeField] private Color _color = Color.white;
+ [HideInInspector] [SerializeField] private Color _defaultColor;
+
+ public override void Init(UXControllerStateRecorder recorder)
+ {
+ if (recorder == null) return;
+
+ if (recorder.TryGetComponent(out var text))
+ {
+ _defaultColor = text.color;
+ }
+ else if (recorder.TryGetComponent(out var tmp))
+ {
+ _defaultColor = tmp.color;
+ }
+ }
+
+ public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
+ {
+ if (recorder == null) return;
+
+ Color targetColor = (entryIndex == selectionIndex) ? _color : _defaultColor;
+
+ if (recorder.TryGetComponent(out var text))
+ {
+ text.color = targetColor;
+ }
+ else if (recorder.TryGetComponent(out var tmp))
+ {
+ tmp.color = targetColor;
+ }
+ }
+
+ public override bool Valid(UXControllerStateRecorder recorder)
+ {
+ return recorder != null &&
+ (recorder.GetComponent() != null || recorder.GetComponent() != null);
+ }
+
+ public override string GetDescription()
+ {
+ return $"匹配时: 颜色={_color}, 默认={_defaultColor}";
+ }
+ }
+}
diff --git a/Runtime/UXComponent/Controller/Property/TextContentState.cs b/Runtime/UXComponent/Controller/Property/TextContentState.cs
new file mode 100644
index 0000000..24dc195
--- /dev/null
+++ b/Runtime/UXComponent/Controller/Property/TextContentState.cs
@@ -0,0 +1,49 @@
+using System;
+using UnityEngine;
+using UnityEngine.UI;
+using TMPro;
+
+namespace AlicizaX.UI
+{
+ ///
+ /// Text 内容状态控制
+ /// 控制 Text 或 TextMeshProUGUI 的文本内容
+ ///
+ [Serializable]
+ [ControlerStateName("Text/Content")]
+ [ControlerStateAttachType(true)]
+ public class TextContentState : ControllerStateBase
+ {
+ [SerializeField] [TextArea(3, 10)] private string _text = "";
+
+ public override void Init(UXControllerStateRecorder recorder)
+ {
+ }
+
+ public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
+ {
+ if (recorder == null || entryIndex != selectionIndex) return;
+
+ if (recorder.TryGetComponent(out var text))
+ {
+ text.text = _text;
+ }
+ else if (recorder.TryGetComponent(out var tmp))
+ {
+ tmp.text = _text;
+ }
+ }
+
+ public override bool Valid(UXControllerStateRecorder recorder)
+ {
+ return recorder != null &&
+ (recorder.GetComponent() != null || recorder.GetComponent() != null);
+ }
+
+ public override string GetDescription()
+ {
+ string preview = _text.Length > 30 ? _text.Substring(0, 30) + "..." : _text;
+ return $"匹配时: \"{preview}\"";
+ }
+ }
+}
diff --git a/Runtime/UXComponent/Controller/Property/TransformPositionState.cs b/Runtime/UXComponent/Controller/Property/TransformPositionState.cs
new file mode 100644
index 0000000..ac29775
--- /dev/null
+++ b/Runtime/UXComponent/Controller/Property/TransformPositionState.cs
@@ -0,0 +1,44 @@
+using System;
+using UnityEngine;
+
+namespace AlicizaX.UI
+{
+ ///
+ /// Transform 位置状态控制
+ /// 控制 RectTransform 的锚点位置
+ ///
+ [Serializable]
+ [ControlerStateName("Transform/Position")]
+ [ControlerStateAttachType(true)]
+ public class TransformPositionState : ControllerStateBase
+ {
+ [SerializeField] private Vector2 _position;
+ [HideInInspector] [SerializeField] private Vector2 _defaultPosition;
+
+ public override void Init(UXControllerStateRecorder recorder)
+ {
+ if (recorder != null && recorder.TryGetComponent(out var rect))
+ {
+ _defaultPosition = rect.anchoredPosition;
+ }
+ }
+
+ public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
+ {
+ if (recorder != null && recorder.TryGetComponent(out var rect))
+ {
+ rect.anchoredPosition = (entryIndex == selectionIndex) ? _position : _defaultPosition;
+ }
+ }
+
+ public override bool Valid(UXControllerStateRecorder recorder)
+ {
+ return recorder != null && recorder.GetComponent() != null;
+ }
+
+ public override string GetDescription()
+ {
+ return $"匹配时: 位置={_position}, 默认={_defaultPosition}";
+ }
+ }
+}
diff --git a/Runtime/UXComponent/Controller/Property/TransformRotationState.cs b/Runtime/UXComponent/Controller/Property/TransformRotationState.cs
new file mode 100644
index 0000000..a8ba251
--- /dev/null
+++ b/Runtime/UXComponent/Controller/Property/TransformRotationState.cs
@@ -0,0 +1,44 @@
+using System;
+using UnityEngine;
+
+namespace AlicizaX.UI
+{
+ ///
+ /// Transform 旋转状态控制
+ /// 控制对象的本地欧拉角旋转
+ ///
+ [Serializable]
+ [ControlerStateName("Transform/Rotation")]
+ [ControlerStateAttachType(true)]
+ public class TransformRotationState : ControllerStateBase
+ {
+ [SerializeField] private Vector3 _rotation;
+ [HideInInspector] [SerializeField] private Vector3 _defaultRotation;
+
+ public override void Init(UXControllerStateRecorder recorder)
+ {
+ if (recorder != null && recorder.transform != null)
+ {
+ _defaultRotation = recorder.transform.localEulerAngles;
+ }
+ }
+
+ public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
+ {
+ if (recorder != null && recorder.transform != null)
+ {
+ recorder.transform.localEulerAngles = (entryIndex == selectionIndex) ? _rotation : _defaultRotation;
+ }
+ }
+
+ public override bool Valid(UXControllerStateRecorder recorder)
+ {
+ return recorder != null && recorder.transform != null;
+ }
+
+ public override string GetDescription()
+ {
+ return $"匹配时: 旋转={_rotation}, 默认={_defaultRotation}";
+ }
+ }
+}
diff --git a/Runtime/UXComponent/Controller/Property/TransformScaleState.cs b/Runtime/UXComponent/Controller/Property/TransformScaleState.cs
new file mode 100644
index 0000000..0e2f324
--- /dev/null
+++ b/Runtime/UXComponent/Controller/Property/TransformScaleState.cs
@@ -0,0 +1,44 @@
+using System;
+using UnityEngine;
+
+namespace AlicizaX.UI
+{
+ ///
+ /// Transform 缩放状态控制
+ /// 控制对象的本地缩放
+ ///
+ [Serializable]
+ [ControlerStateName("Transform/Scale")]
+ [ControlerStateAttachType(true)]
+ public class TransformScaleState : ControllerStateBase
+ {
+ [SerializeField] private Vector3 _scale = Vector3.one;
+ [HideInInspector] [SerializeField] private Vector3 _defaultScale;
+
+ public override void Init(UXControllerStateRecorder recorder)
+ {
+ if (recorder != null && recorder.transform != null)
+ {
+ _defaultScale = recorder.transform.localScale;
+ }
+ }
+
+ public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
+ {
+ if (recorder != null && recorder.transform != null)
+ {
+ recorder.transform.localScale = (entryIndex == selectionIndex) ? _scale : _defaultScale;
+ }
+ }
+
+ public override bool Valid(UXControllerStateRecorder recorder)
+ {
+ return recorder != null && recorder.transform != null;
+ }
+
+ public override string GetDescription()
+ {
+ return $"匹配时: 缩放={_scale}, 默认={_defaultScale}";
+ }
+ }
+}