StateSwitcher
Namespace: Vortex.Unity.UI.StateSwitcher
Assembly: ru.vortex.unity.ui.misc
Purpose
State machine for visual and behavioral switching. UIStateSwitcher manages an array of named states, each containing a set of StateItem.
Capabilities:
- Switching by index, name, or enum
- 7 built-in StateItem types: GameObjects, Animator (bool/int), Colors (with animation), Sprites, Events, TweenerHub
StateSwitcherAttributefor enum binding with Inspector visualizationOnStateSwitchevent on state change- Reentrancy protection
Alt+S/Ctrl+Alt+Shotkeys — add aUIStateSwitcherto an object or as a separate layer
Out of scope:
- Transition animations between states (use
TweenerHubSwitch,ColorsSwitch, orStateView<TEnum>from TweenerSystem when the states are animations) - State selection logic (layer 3/4)
Dependencies
| Dependency | Purpose |
|---|---|
Vortex.Unity.UI.TweenerSystem |
TweenerHub — integration via TweenerHubSwitch |
Vortex.Unity.UI.TweenerSystem.UniTaskTweener |
AsyncTween — color animation in ColorsSwitch |
Vortex.Unity.EditorTools |
DrawingUtility, ToolsSettings — StateSwitcherDrawer rendering |
Vortex.Unity.AppSystem.System.TimeSystem |
TimeController — frame-delayed switching in GameObjectsSwitch |
Vortex.Core.ExtensibleEnumSystem |
ExtensibleEnum — Set(ExtensibleEnum) overload by Order |
| Odin Inspector | [ValueDropdown], [ShowInInspector], [Button] |
Architecture
StateSwitcher/
├── UIStateSwitcher.cs # State machine (MonoBehaviour)
├── StateItem.cs # Abstract behavior base
├── Items/
│ ├── GameObjectsSwitch.cs # SetActive on GameObject array
│ ├── AnimatorBoolSwitch.cs # SetBool on Animator
│ ├── AnimatorStateSwitch.cs # SetInteger on Animator
│ ├── ColorsSwitch.cs # Color (instant or animated)
│ ├── SpritesSwitch.cs # Sprite on SpriteRenderer/Image
│ ├── EventFire.cs # UnityEvent on activation
│ └── TweenerHubSwitch.cs # Forward/Back on TweenerHub
└── Handlers/
└── OnEnableStateRunner.cs # Switch on OnEnable
UIStateSwitcher
MonoBehaviour with a StateData array. Each StateData is a named state with a StateItem[] array.
On switch:
- Calls
DefaultState()on all items of the previous state (Danger point!) - Calls
Set()on all items of the new state - Fires
OnStateSwitchevent
API
switcher.Set(0); // by index
switcher.Set("Active"); // by name
switcher.Set(MyEnum.Active); // by enum
switcher.Set((byte)2); // by byte
switcher.Set(myExtensibleEnum); // by ExtensibleEnum (via Order, null → no-op)
switcher.ResetStates(); // reset all items + initial state
int current = switcher.State; // current state (-1 = none)
StateData[] all = switcher.States; // all states array
switcher.OnStateSwitch += OnSwitch; // event (StateData or null)
int index = switcher.GetState("name"); // index by name (-1 = not found)
| Inspector Field | Type | Description |
|---|---|---|
states |
StateData[] |
State array |
stateOnEnable |
int |
Initial state (dropdown) |
duplicateOnCreate |
bool |
Editor-only: clone items from last state when adding new one |
StateItem
Abstract behavior class. On state activation — Set(), on deactivation — DefaultState().
| Implementation | Set() | DefaultState() |
|---|---|---|
GameObjectsSwitch |
SetActive(true) on array (optionally frame-delayed via onDelayed) |
SetActive(false) (optionally frame-delayed via offDelayed) |
AnimatorBoolSwitch |
SetBool(name, true) |
SetBool(name, false) |
AnimatorStateSwitch |
SetInteger(name, value) |
SetInteger(name, default) |
ColorsSwitch |
Set color (instant or via AsyncTween) |
Revert to Color.white |
SpritesSwitch |
Set sprite | Set null |
EventFire |
UnityEvent.Invoke() |
Nothing |
TweenerHubSwitch |
tweener.Forward() |
tweener.Back() |
ColorsSwitch
Supports SpriteRenderer, Graphic (Image, Text), Outline. Modes:
- Instant color change
- Animated via
AsyncTweenwith configurable duration and curve - Optional start color:
_useOwnStartColor = true— takes current color from the object,false— uses the_startColorfield
Inspector button Get from... — captures current color from first object.
StateSwitcherAttribute
Attribute for binding UIStateSwitcher to an enum. Used with StateSwitcherDrawer.
[SerializeField, StateSwitcher(typeof(MyStatesEnum))]
private UIStateSwitcher switcher;
In Inspector displays a state table:
- Index, description (from
[Tooltip]/[LabelText]), name from switcher - Active state highlighting
- Click to switch
- Sync button — synchronizes state names with enum descriptions
Hotkeys
For selected scene objects or objects of an open prefab (UI/UIBuilder/Shortcuts/UIStateSwitcherShortcut.cs):
| Shortcut | Menu | Action |
|---|---|---|
Alt+S |
Tools/Vortex/UI/Add UIStateSwitcher |
Add a UIStateSwitcher to the object itself; skipped where one already exists |
Ctrl+Alt+S |
Tools/Vortex/UI/Add UIStateSwitcher Layer |
A child layer [UIStateSwitcher] with a switcher: first in the hierarchy, at the zero point, on a plain Transform (RectTransform is removed); new layers are selected |
Assets in the Project window are not affected. Undone in one step. The menu items live in the UIBuilder package together with the other layout hotkeys; adding the component and creating the layer is shared code in EditorTools/HierarchyTools/HierarchyLayers.cs, the same as for the TweenerHub hotkeys (Alt+T / Ctrl+Alt+T).
OnEnableStateRunner
MonoBehaviour — switches a UIStateSwitcher to a given state on OnEnable.
| Field | Type | Description |
|---|---|---|
_stateSwitcher |
UIStateSwitcher |
Target switcher |
_stateToOpen |
int |
State index |
Edge Cases
| Situation | Behavior |
|---|---|
Set() with out-of-range index |
LogError, state unchanged |
Set() with same index |
Skipped (state not reapplied) |
Set() during transition |
Reentrancy guard (_isSwitching) |
Set() before Awake |
State saved in _startState, applied in Awake |
GetState("nonexistent") |
Returns -1 |
Set("nonexistent") |
LogError, then falls back to stateOnEnable — the switcher never sits in an undefined state |
StateItem.Set() throws an exception |
A try/catch wraps the foreach: LogError + LogException, the remaining StateItems in this state are not applied (fail fast, do not mask the actual problem) |
ColorsSwitch with _smoothChange and zero _duration |
Instant change (AsyncTween with duration ≤ 0) |
Duplicate DropDownGroupName/DropDownItemName across StateItem classes |
LogError, duplicate skipped in dropdown |