This commit is contained in:
陈思海 2026-03-11 15:23:44 +08:00
parent 49ecff8262
commit 839af11027
14 changed files with 582 additions and 507 deletions

View File

@ -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);

View File

@ -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();

View File

@ -0,0 +1,44 @@
using System;
using UnityEngine;
namespace AlicizaX.UI
{
/// <summary>
/// CanvasGroup 透明度状态控制
/// 控制 CanvasGroup 的 Alpha 值
/// </summary>
[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<CanvasGroup>(out var canvasGroup))
{
_defaultAlpha = canvasGroup.alpha;
}
}
public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
{
if (recorder != null && recorder.TryGetComponent<CanvasGroup>(out var canvasGroup))
{
canvasGroup.alpha = (entryIndex == selectionIndex) ? _alpha : _defaultAlpha;
}
}
public override bool Valid(UXControllerStateRecorder recorder)
{
return recorder != null && recorder.GetComponent<CanvasGroup>() != null;
}
public override string GetDescription()
{
return $"匹配时: 透明度={_alpha:F2}, 默认={_defaultAlpha:F2}";
}
}
}

View File

@ -0,0 +1,49 @@
using System;
using UnityEngine;
namespace AlicizaX.UI
{
/// <summary>
/// CanvasGroup 交互状态控制
/// 控制 CanvasGroup 的可交互性和射线检测
/// </summary>
[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<CanvasGroup>(out var canvasGroup))
{
_defaultInteractable = canvasGroup.interactable;
_defaultBlocksRaycasts = canvasGroup.blocksRaycasts;
}
}
public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
{
if (recorder != null && recorder.TryGetComponent<CanvasGroup>(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<CanvasGroup>() != null;
}
public override string GetDescription()
{
return $"匹配时: 可交互={_interactable}, 射线检测={_blocksRaycasts}";
}
}
}

View File

@ -0,0 +1,45 @@
using System;
using UnityEngine;
namespace AlicizaX.UI
{
/// <summary>
/// GameObject 激活状态控制
/// 控制对象的显示/隐藏
/// </summary>
[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 ? "" : "")}";
}
}
}

View File

@ -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<RectTransform>(out var rect))
{
_defaultPosition = rect.anchoredPosition;
}
}
public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
{
if (recorder != null && recorder.TryGetComponent<RectTransform>(out var rect))
{
rect.anchoredPosition = (entryIndex == selectionIndex) ? _position : _defaultPosition;
}
}
public override bool Valid(UXControllerStateRecorder recorder)
{
return recorder != null && recorder.GetComponent<RectTransform>() != 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<Graphic>(out var graphic))
{
_defaultColor = graphic.color;
}
}
public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
{
if (recorder != null && recorder.TryGetComponent<Graphic>(out var graphic))
{
graphic.color = (entryIndex == selectionIndex) ? _color : _defaultColor;
}
}
public override bool Valid(UXControllerStateRecorder recorder)
{
return recorder != null && recorder.GetComponent<Graphic>() != 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<Graphic>(out var graphic))
{
_defaultMaterial = graphic.material;
}
}
public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
{
if (recorder != null && recorder.TryGetComponent<Graphic>(out var graphic))
{
graphic.material = (entryIndex == selectionIndex) ? _material : _defaultMaterial;
}
}
public override bool Valid(UXControllerStateRecorder recorder)
{
return recorder != null && recorder.GetComponent<Graphic>() != 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<Image>(out var image))
{
_defaultSprite = image.sprite;
}
}
public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
{
if (recorder != null && recorder.TryGetComponent<Image>(out var image))
{
image.sprite = (entryIndex == selectionIndex) ? _sprite : _defaultSprite;
}
}
public override bool Valid(UXControllerStateRecorder recorder)
{
return recorder != null && recorder.GetComponent<Image>() != 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<Text>(out var text))
{
text.text = _text;
}
else if (recorder.TryGetComponent<TextMeshProUGUI>(out var tmp))
{
tmp.text = _text;
}
}
public override bool Valid(UXControllerStateRecorder recorder)
{
return recorder != null &&
(recorder.GetComponent<Text>() != null || recorder.GetComponent<TextMeshProUGUI>() != 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<Text>(out var text))
{
_defaultColor = text.color;
}
else if (recorder.TryGetComponent<TextMeshProUGUI>(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<Text>(out var text))
{
text.color = targetColor;
}
else if (recorder.TryGetComponent<TextMeshProUGUI>(out var tmp))
{
tmp.color = targetColor;
}
}
public override bool Valid(UXControllerStateRecorder recorder)
{
return recorder != null &&
(recorder.GetComponent<Text>() != null || recorder.GetComponent<TextMeshProUGUI>() != 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<CanvasGroup>(out var canvasGroup))
{
_defaultAlpha = canvasGroup.alpha;
}
}
public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
{
if (recorder != null && recorder.TryGetComponent<CanvasGroup>(out var canvasGroup))
{
canvasGroup.alpha = (entryIndex == selectionIndex) ? _alpha : _defaultAlpha;
}
}
public override bool Valid(UXControllerStateRecorder recorder)
{
return recorder != null && recorder.GetComponent<CanvasGroup>() != 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<CanvasGroup>(out var canvasGroup))
{
_defaultInteractable = canvasGroup.interactable;
_defaultBlocksRaycasts = canvasGroup.blocksRaycasts;
}
}
public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
{
if (recorder != null && recorder.TryGetComponent<CanvasGroup>(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<CanvasGroup>() != null;
}
public override string GetDescription()
{
return $"When Matched: Interactable={_interactable}, Raycast={_blocksRaycasts}";
}
}
#endregion
}

View File

@ -0,0 +1,45 @@
using System;
using UnityEngine;
using UnityEngine.UI;
namespace AlicizaX.UI
{
/// <summary>
/// Graphic 颜色状态控制
/// 控制 UI 图形组件的颜色
/// </summary>
[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<Graphic>(out var graphic))
{
_defaultColor = graphic.color;
}
}
public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
{
if (recorder != null && recorder.TryGetComponent<Graphic>(out var graphic))
{
graphic.color = (entryIndex == selectionIndex) ? _color : _defaultColor;
}
}
public override bool Valid(UXControllerStateRecorder recorder)
{
return recorder != null && recorder.GetComponent<Graphic>() != null;
}
public override string GetDescription()
{
return $"匹配时: 颜色={_color}, 默认={_defaultColor}";
}
}
}

View File

@ -0,0 +1,47 @@
using System;
using UnityEngine;
using UnityEngine.UI;
namespace AlicizaX.UI
{
/// <summary>
/// Graphic 材质状态控制
/// 控制 UI 图形组件的材质
/// </summary>
[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<Graphic>(out var graphic))
{
_defaultMaterial = graphic.material;
}
}
public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
{
if (recorder != null && recorder.TryGetComponent<Graphic>(out var graphic))
{
graphic.material = (entryIndex == selectionIndex) ? _material : _defaultMaterial;
}
}
public override bool Valid(UXControllerStateRecorder recorder)
{
return recorder != null && recorder.GetComponent<Graphic>() != null;
}
public override string GetDescription()
{
string matched = _material != null ? _material.name : "无";
string defaultVal = _defaultMaterial != null ? _defaultMaterial.name : "无";
return $"匹配时: {matched}, 默认: {defaultVal}";
}
}
}

View File

@ -0,0 +1,47 @@
using System;
using UnityEngine;
using UnityEngine.UI;
namespace AlicizaX.UI
{
/// <summary>
/// Image 精灵图状态控制
/// 控制 Image 组件的 Sprite
/// </summary>
[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<Image>(out var image))
{
_defaultSprite = image.sprite;
}
}
public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
{
if (recorder != null && recorder.TryGetComponent<Image>(out var image))
{
image.sprite = (entryIndex == selectionIndex) ? _sprite : _defaultSprite;
}
}
public override bool Valid(UXControllerStateRecorder recorder)
{
return recorder != null && recorder.GetComponent<Image>() != null;
}
public override string GetDescription()
{
string matched = _sprite != null ? _sprite.name : "无";
string defaultVal = _defaultSprite != null ? _defaultSprite.name : "无";
return $"匹配时: {matched}, 默认: {defaultVal}";
}
}
}

View File

@ -0,0 +1,61 @@
using System;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
namespace AlicizaX.UI
{
/// <summary>
/// Text 颜色状态控制
/// 控制 Text 或 TextMeshProUGUI 的文本颜色
/// </summary>
[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<Text>(out var text))
{
_defaultColor = text.color;
}
else if (recorder.TryGetComponent<TextMeshProUGUI>(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<Text>(out var text))
{
text.color = targetColor;
}
else if (recorder.TryGetComponent<TextMeshProUGUI>(out var tmp))
{
tmp.color = targetColor;
}
}
public override bool Valid(UXControllerStateRecorder recorder)
{
return recorder != null &&
(recorder.GetComponent<Text>() != null || recorder.GetComponent<TextMeshProUGUI>() != null);
}
public override string GetDescription()
{
return $"匹配时: 颜色={_color}, 默认={_defaultColor}";
}
}
}

View File

@ -0,0 +1,49 @@
using System;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
namespace AlicizaX.UI
{
/// <summary>
/// Text 内容状态控制
/// 控制 Text 或 TextMeshProUGUI 的文本内容
/// </summary>
[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<Text>(out var text))
{
text.text = _text;
}
else if (recorder.TryGetComponent<TextMeshProUGUI>(out var tmp))
{
tmp.text = _text;
}
}
public override bool Valid(UXControllerStateRecorder recorder)
{
return recorder != null &&
(recorder.GetComponent<Text>() != null || recorder.GetComponent<TextMeshProUGUI>() != null);
}
public override string GetDescription()
{
string preview = _text.Length > 30 ? _text.Substring(0, 30) + "..." : _text;
return $"匹配时: \"{preview}\"";
}
}
}

View File

@ -0,0 +1,44 @@
using System;
using UnityEngine;
namespace AlicizaX.UI
{
/// <summary>
/// Transform 位置状态控制
/// 控制 RectTransform 的锚点位置
/// </summary>
[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<RectTransform>(out var rect))
{
_defaultPosition = rect.anchoredPosition;
}
}
public override void Execute(UXControllerStateRecorder recorder, int entryIndex, int selectionIndex)
{
if (recorder != null && recorder.TryGetComponent<RectTransform>(out var rect))
{
rect.anchoredPosition = (entryIndex == selectionIndex) ? _position : _defaultPosition;
}
}
public override bool Valid(UXControllerStateRecorder recorder)
{
return recorder != null && recorder.GetComponent<RectTransform>() != null;
}
public override string GetDescription()
{
return $"匹配时: 位置={_position}, 默认={_defaultPosition}";
}
}
}

View File

@ -0,0 +1,44 @@
using System;
using UnityEngine;
namespace AlicizaX.UI
{
/// <summary>
/// Transform 旋转状态控制
/// 控制对象的本地欧拉角旋转
/// </summary>
[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}";
}
}
}

View File

@ -0,0 +1,44 @@
using System;
using UnityEngine;
namespace AlicizaX.UI
{
/// <summary>
/// Transform 缩放状态控制
/// 控制对象的本地缩放
/// </summary>
[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}";
}
}
}