Skip to main content

Contributors: Jellejurre, JustSleightly

Sub-Animator Techniques

While most effects can be accomplished using traditional StateMachines, this article explores some niche techniques utilizing sub-Animators; Animators other than the main avatar root Animator.

Animator Enable/Disable

Disabling the animator pauses it in the current state, a technique once employed to create a 'Cycler' - a sub-animator cycling between states by toggling its enable/disable status with exit time. Upon re-enabling, the animator seamlessly resumes from where it was paused.

Note: Be aware that this behavior differs in Unity. In Unity, disabling and enabling the animator resets its state.


Animations that disable/enable Animators use a Behaviour Enabled keyframe property, and have to be made either with a script or by carefully editing an animation file.

GameObject Enable/Disable

Disabling and enabling the GameObject with an animator resets the animator to its initial state, unless the “Keep Animator Controller State on Disable” flag is enabled. To access this flag, enable Debug in the inspector settings.

Keep in mind that you cannot disable the Animator or the GameObject for your own avatar.

Where to enable the debug view

Where to enable the debug view

Culling Mode

There are three culling modes for animators, as detailed in Animators:

  • Always Animate: Animates the entire avatar, even when offscreen.
  • Cull Update Transforms: Disables changing values of transforms when renderers are not visible, affecting GameObjects, components, and blendshapes. Exceptions include animating Animated Animator Parameters and triggering State Machine Behaviours.
  • Cull Completely: Freezes the entire animator when renderers are not visible, halting logic, transitions, and animations.

On the VRChat local avatar Animator, this setting defaults to 'Always Animate' for local avatars and 'Cull Update Transforms' for remote avatars. Animators on children GameObjects remain unaffected.

This allows one to do some logic to determine of a mesh is being rendered.

If you have a sub-Animator with one Mesh under it, and it’s set to Cull Completely, then it will stop animating when the Mesh is not looked at locally. One way this can be detected is by animating an object both in the FX controller and in this sub-Animator. The sub-Animator will overwrite the FX controller, unless the sub-Animator is culled, at which point the FX controller takes over. This is used, to toggle a VRC Contact Sender, which determines the value of a VRC Contact Receiver, whose parameter can be picked up in the FX layer. This is the inner workings of VRLabs’ IsRendering Detection.

Last Updated: 31 March 2024 08:54:00