Warning
Work in progress. Aspid.Core.HSM is under active development. The public API is not yet stable and may change without notice between releases. Use with care in production.
Aspid.Core.HSM is a Roslyn-powered Hierarchical State Machine for Unity, built from small composable abstractions: states with Enter / Exit hooks, a parent→child hierarchy expressed through the generic IChildState<TParent> interface, pluggable per-frame controllers (IUpdateController, IFixedUpdateController, ILateUpdateController, …) aggregated via [ControllerGroup], composites that pick their own leaf (IEntrySelector), declarative guarded transitions ([Transition]), extension states ([ExtensionFor]), state scopes and async enter/exit (ChangeStateAsync). IEnteredController runs once the transition that entered a state has completed, with a token that lives as long as the state. MonoStateMachine wires it all to the Unity MonoBehaviour lifecycle.
Requires Unity 6000.0.53f1 or newer. Install UniTask first, then Aspid.Core.HSM.
Open Window → Package Manager, choose + → Install package from git URL…, paste the URL below and press Install. If UniTask is already installed, skip this step.
https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask#2.5.11
Why install UniTask separately?
HSM's async enter/exit controllers use UniTask, so the package does not compile without it. UPM does not resolve Git dependencies transitively; install UniTask explicitly before HSM. An existing OpenUPM installation works as well.
![]() |
|
https://github.com/VPDPersonal/Aspid.Core.HSM.git#upm-preview
The URL installs the latest preview release (alpha, beta, rc, …); Update in the Package Manager installs the next one. The public API may change between previews.
Pin a version and choose a release channel
To keep a project on a specific preview, use its immutable release tag:
https://github.com/VPDPersonal/Aspid.Core.HSM.git#upm-preview/0.0.1-alpha.7
See Releases for available versions. There is no stable release yet, so use #upm-preview. The Release workflow creates the upm branch and upm/<version> tags when the first stable version ships.
Troubleshooting
Compile errors mentioning Cysharp or UniTask. Install UniTask using the first URL above, then let Unity recompile.
Unity is older than 6000.0.53f1. Upgrade to the supported minimum before installing HSM. Check the Editor version in Help → About Unity (Unity → About Unity on macOS).
Import it from the package's Samples tab. Its scripts read input through the Input System, so install com.unity.inputsystem from the Unity Registry first, or the sample does not compile.
ChangeStateAsync, TransitionToAsync and TransitionViaAsync tell why they ended without completing. Every case is an
OperationCanceledException, so an existing catch (OperationCanceledException) keeps catching all of them. The cause is
recorded when the transition is cancelled, not guessed from the machine's state when the exception arrives.
| Exception | Meaning | Usual handling |
|---|---|---|
TransitionSupersededException |
A newer transition took over; SupersedingState names its target, RollbackExceptions holds what the rollback threw |
Nothing: the newer transition owns the machine |
StateMachineDisposedException |
The machine was disposed | Nothing: the machine is gone |
OperationCanceledException (exactly) |
The caller's token, or an enter/exit callback cancelled itself (a load gave up) | A failure: apply your error policy |
| any other exception | An enter, exit or hook threw | A failure: apply your error policy |
A stage that waits for an event after its state is entered implements IAsyncEnteredController: the machine starts
OnEnteredAsync(StateEntry entry) once the transition is over and owns its outcome. The state exiting, the next
transition being superseded and the machine being disposed stay silent; any other failure goes to the nearest
IEnteredFailedController on the stage's state or above it when the stage started, or to the machine's
OnEnteredFailed. Leave the state through entry.ChangeStateAsync<T>(), so a failure of that transition is reported
even after the state has exited. Once the state has exited, the entry starts no transition.
MIT.
