Control VRChat Avatar Animator States with Parameters

Use a Bool, Int, or Float parameter to control an avatar state in VRChat. VRChat currently advises against using Unity Trigger parameters for avatar state because their values can become desynchronized for remote viewers, mirrors, or different platform versions of the avatar.

Quick setup

Create one parameter with the same name and type in the Animator Controller and Expression Parameters asset, then drive it from an Expressions Menu control.

  1. Choose `Bool`, `Int`, or `Float` for the state you need.
  2. Add the parameter to the correct playable-layer controller.
  3. Add the matching custom parameter and menu control.
  4. Create transitions into and out of every controlled state.
  5. Test the result in VRChat, including the view seen by another player.
Do not use a Trigger for persistent avatar state

A Unity Trigger resets after a transition consumes it, but VRChat does not recommend Trigger parameters for avatar controllers. Use a Bool, Int, or Float so the state has an explicit value that can synchronize and recover.

Choose the Parameter Type

Type Best for Example condition
Bool One feature that is either on or off HatOn is true
Int Several mutually exclusive choices Outfit equals 2
Float A continuous value or blend Hue greater than 0.5

VRChat custom expression parameters support Bool, Int, and Float. The parameter type in the Animator Controller should match the type in the Expression Parameters asset. VRChat can convert mismatched types, but matching them keeps transition conditions and defaults predictable.

Put the Animation in the Correct Playable Layer

VRChat combines its playable layers into the avatar's runtime Animator. Add your controller to a playable-layer slot on the Avatar Descriptor; do not assign the custom controller directly to the root Animator component.

Layer Use it for
Gesture Transform animation for gestures, ears, tails, wings, and other non-humanoid bones
Action Full-body transform actions that temporarily override other motion
FX GameObject toggles, blend shapes, materials, particles, and other non-transform effects

Most clothing toggles, material changes, and facial effects belong in the FX playable layer. VRChat advises using a different controller for each playable layer.

Build a Reliable Toggle

The following example uses a Bool named HatOn.

1. Add the Animator parameter

  1. Open the Animator Controller used by the avatar's FX playable layer.
  2. In the Parameters tab, add a Bool named HatOn.
  3. Create an Off state and an On state with the appropriate animation clips.
  4. Set the state that matches the parameter's default value as the layer default.

Parameter names are case-sensitive in practice because every asset must refer to the same name. Copy the name rather than retyping variants such as hatOn or Hat On.

2. Add transitions in both directions

Create these transitions:

From To Condition
Off On HatOn is true
On Off HatOn is false

For a menu-driven toggle, disable Has Exit Time on both transitions so the parameter condition can be evaluated immediately. Keep transition duration short when the clips simply enable or disable an object.

Every state needs a way out

VRChat's animator guidance says parameters can change at any time and warns against dead ends. A state that only has an entry transition can leave the avatar stuck after the parameter changes.

3. Add the Expression Parameter

  1. Select the Expression Parameters asset assigned to the Avatar Descriptor.
  2. Add a parameter named HatOn.
  3. Set its type to Bool and choose the same default used by the Animator Controller.
  4. Enable Saved only if the choice should persist when the user changes worlds or avatars.
  5. Enable Synced if other players need to see the result.

Do not add VRChat's built-in parameters to the Expression Parameters asset. Built-in values such as GestureLeft, VelocityMagnitude, and IsLocal become available when you add matching parameters to a playable-layer controller.

4. Add the Expressions Menu control

  1. Open the Expressions Menu asset assigned to the avatar.
  2. Add a control and set its type to Toggle.
  3. Select HatOn as its parameter.
  4. Give the control a direct label such as Hat.

Use Button for a value that should remain active only while the control is pressed, Toggle for an on/off Bool, Sub-Menu for another menu asset, and puppet controls for Float-based input.

Use an Int for Multiple Choices

A single Int is cleaner than several competing Bools when only one option may be active. For example, an Outfit parameter could use:

Value State
0 Default outfit
1 Outfit A
2 Outfit B

Create a state for each value and give every state transitions for the other valid values. In the Expressions Menu, use controls that set the same Int parameter to the required value.

Change Parameters from Animator States

Add VRChat's Avatar Parameter Driver state behavior when entering a state should set, add, randomize, or copy another custom parameter. Set, Random, and Copy support Bool parameters; Add is intended for numeric values.

For Add or Random, VRChat warns that remote results may differ. Its documentation recommends using a synced destination parameter and running the driver locally for those operations. Built-in VRChat parameters are read-only and cannot be changed by an Expressions Menu or Avatar Parameter Driver.

Test Before Uploading Publicly

  1. Confirm the controller is assigned to the intended playable-layer slot.
  2. Confirm parameter name, type, and default match across the controller and Expression Parameters asset.
  3. Use the SDK Builder to resolve avatar validation errors.
  4. Test every menu value and every return transition.
  5. Check the avatar after a reset, world change, and avatar reload.
  6. Test with another client or player when the parameter is synced.
  7. For PC and Android versions, use the same Expression Parameters asset so parameter order and types remain aligned.
The menu control changes, but the animation does not.

Check that the playable-layer controller contains the parameter and that its name and type match the Expression Parameters asset. Then inspect the transition condition and confirm the controller is assigned to the correct custom playable layer.

The avatar enters a state but never leaves it.

Add a return transition with the inverse Bool condition or the other valid Int values. If the transition has a condition, check whether Has Exit Time is delaying evaluation until the animation reaches its configured exit time.

The toggle resets after changing worlds or avatars.

Enable Saved on the custom Expression Parameter if the setting should persist. Also confirm that the Animator Controller and Expression Parameters asset use the same default value.

Other players cannot see the change.

Enable Synced on the custom Expression Parameter, then test with another player or client. Local editor playback does not verify the networked result.

The PC and Android versions show different states.

VRChat synchronizes cross-platform custom parameters by list position and type rather than by name. Use the same Expression Parameters asset for both platform versions, including parameters a reduced version does not animate.

A Trigger works locally but behaves inconsistently elsewhere.

Replace it with a Bool, Int, or Float that represents the state explicitly. VRChat warns that Trigger parameters can desynchronize for remote viewers, mirrors, and different avatar versions.

Two layers fight over the same animation.

Check playable-layer order and Avatar Masks. Later playable layers can override earlier ones, and FX should not animate humanoid transforms. Keep each effect in the layer intended for that kind of animation.

Official References

Related Guides

Topics: avatar animator parameters, expression menus, transitions, playable layers