State Visualizer — MRTK3
StateVisualizer is a low-code designer-friendly interface for authoring visual feedback in response to interaction states. It allows for both complex animation-based effects as well as common pre-made effects.
In MRTK3, we enforce separation of state and visuals. Interactables are responsible for their interaction logic and state, but are designed not to render their own visuals or effects based on their state. The motivation for this separation is that state and interaction logic can be reused across multiple visual contexts, and that the visual feedback and art direction of an interaction can be customized without touching the underlying state or interaction. In addition, mixing state into visuals can result in unmaintainable code with complex, hard-to-understand relationships between visual effects and the interactions they represent.
StateVisualizer, as a result, is largely stateless. It listens to an associated StatefulInteractable and executes a graph of
IEffects based on the current interaction state. Complex state like
Selectedness and passive/active hover intent is exposed for use in StateVisualizer. Some effects can respond to the fractional selection value to drive delightful "analog" effects that respond to the user's motion, pinch, or press.
StateVisualizer is partially built on the Unity Playables API.
How to use
Add StateVisualizer to your interactable, along with an Animator. Choose a state, and add your desired effects. Ensure that the
Interactable property is set if the StateVisualizer can't find your interactable at runtime.
You do NOT need an Animator Controller on the Animator, except when authoring effects. StateVisualizer drives the Animator directly through the Playables API. StateVisualizer avoids AnimatorControllers for better performance and maintainability.
Authoring animations with StateVisualizer
StateVisualizer doesn't use an AnimatorController, so animations can't be previewed at edit time by default. To resolve this, create a temporary AnimatorController that contains the relevant animations you're working on and reference it in the Animator. Remember, though, that they're not required at runtime and may have an unwanted performance impact if not removed.
MRTK ships example "AuthoringControllers" that we use to author our animation effects on our components. Feel free to duplicate our example for your own needs.
StateVisualizer is built for optimal performance, despite its use of Animators and Unity animations, which in other contexts can be costly at scale. To solve these problems, StateVisualizer intelligently culls the Animator and aggressively minimizes the amount of time that the Animator is running. In addition, the Playables API has significantly better performance than AnimatorController state machines. The lack of AnimatorControllers contributes significantly to both the simplicity of the StateVisualizer system and its performance at scale.
Currently, StateVisualizer polls the interactable state instead of relying on event listeners to only react when necessary. This part of StateVisualizer is under active development and may be refactored to event listeners for even better performance.
||Tints a list of
These blend operations will also blend on top of any other tints or animations currently executing on the StateVisualizer graph. Note that if the Tintables have different initial colors, this tint effect may blend incorrectly. Use separate Tint effects for elements with different base colors.
||Performs the exact same operation as
||Sets the target
||Enables or disables the list of GameObjects depending on whether the state is active or inactive.
Most effects that aren't covered by one of the bespoke effect types above can usually be authored as an
AnimationEffect. However, if you'd like to create a new bespoke, non-animation-based effect, you can implement the
IEffect interface or subclass one of our existing effects. See the
IEffect API reference for more details.
StateVisualizer is planned to support custom states in the future. Stay tuned.
Submit and view feedback for