Animate a Hue Shift on a VRChat Avatar
A hue-shift control animates a shader property on an avatar material. You can expose two fixed colors through a Toggle, or blend through the shader's hue range with a Radial Puppet.
The shader must provide the property. A material with a dedicated hue scalar can rotate colors through a hue range; animating an ordinary Color field only interpolates between the recorded endpoint colors.
Record only the intended shader property, preview both endpoint clips, then choose a Toggle or Radial Puppet implementation.
- Confirm the material exposes a hue or color property that changes the intended pixels.
- Create clean default and shifted Animation Clips for one renderer slot.
- Connect those clips to a reversible FX setup and test a private upload.
Video Walkthrough
Video creator: DedZedOffishal
Use the walkthrough for the Unity interaction. Use the binding checks and implementation tables below to keep the animation limited to the intended material property.
A VRChat Toggle sets and resets one parameter. A Radial Puppet drives one Float from 0.0 to 1.0 and keeps its selected radial value after the wearer closes the puppet.
Toggle or Radial Puppet?
| Desired result | Menu control | Parameter | FX setup |
|---|---|---|---|
| Default color and one shifted color | Toggle | Bool |
Two states with reversible transitions |
| Adjustable hue amount | Radial Puppet | Float |
One 1D Blend Tree |
| Several named color presets | Sub-Menu or preset selector | Int or project-specific parameters |
One state per preset |
| Separate red, green, and blue mixing | Three Radial Puppets | Three Floats | Three independent shader inputs |
This guide includes the first two implementations. For three-channel mixing, follow Control Avatar Colors with VRChat RGB Radial Puppets.
What You Need
- A working avatar upload.
- A material whose shader exposes an animatable hue or color property.
- The renderer and material element that should change.
- An Expressions Menu and Expression Parameters asset assigned to the avatar.
- A custom FX Animator Controller assigned to the avatar descriptor.
- A backup or version-control checkpoint before recording clips.
Shader property names and ranges vary. Read the shader's documentation and test the material Inspector instead of assuming a universal property name.
1. Verify the Material Property
Duplicate the material before changing it. Select the duplicate in the Project window and find the property you intend to animate.
- Note the property's current value.
- Move it to another value.
- Confirm the intended mesh area changes.
- Confirm unrelated material features remain unchanged.
- Return the property to its starting value.
Hue Property Versus Color Property
| Property type | What interpolation does |
|---|---|
| Dedicated hue scalar | The shader decides how the numeric value maps around its hue range |
| Color field | Unity blends the recorded color components between endpoints |
| Emission color | Blends the emission color; brightness may also depend on separate shader controls |
| Material reference | Switches or selects whole material assets rather than performing a hue rotation |
If 0 and 1 represent the same point on a cyclic hue property, the values between them can still travel through the shader's full hue range. Confirm this in the material before using those endpoints.
2. Record Clean Animation Clips
Select the avatar root, open Window → Animation → Animation, and create the clips while the intended avatar is selected.
For a two-state control:
Hue_Default.anim
Hue_Shifted.anim
For a continuous radial:
Hue_Min.anim
Hue_Max.anim
Record only the chosen property on the intended renderer and material element.
| Clip | Recorded value | Other properties |
|---|---|---|
Hue_Default or Hue_Min |
Starting or minimum hue | Not recorded |
Hue_Shifted |
Chosen alternate hue | Not recorded |
Hue_Max |
Maximum hue value | Not recorded |
Stop recording, exit Animation Mode, and preview every clip individually.
Inspect the Clip Before Continuing
Remove accidental bindings such as:
- GameObject active state.
- Transform position, rotation, or scale.
- Unrelated blendshapes.
- Other shader properties.
- A different material element on the same renderer.
The clip records the renderer path, material element, and property. Renaming or re-parenting the renderer, reordering the Materials list, or replacing the shader can leave the clip targeting a missing or different binding.
Option A: Build a Two-State Hue Toggle
Use this when the wearer only needs a default and shifted appearance.
3A. Add the Bool Parameter
Add the same parameter to the Expression Parameters asset and FX Animator Controller:
Name: Color/HueShift
Type: Bool
Default: false
Enable Saved if the wearer expects the choice to persist. Enable Synced if other players need to see the chosen hue.
4A. Build the FX Layer
Create an FX layer named Color - Hue Toggle and set its weight to 1.
| State | Motion | Role |
|---|---|---|
Hue Default |
Hue_Default |
Orange default state |
Hue Shifted |
Hue_Shifted |
Alternate hue |
Add both transitions:
| Transition | Condition |
|---|---|
| Hue Default → Hue Shifted | Color/HueShift is true |
| Hue Shifted → Hue Default | Color/HueShift is false |
Disable Has Exit Time and set transition duration to 0 in both directions.
5A. Add the Toggle
In the Expressions Menu:
- Add a control named
Hue Shift. - Set its type to Toggle.
- Assign
Color/HueShift. - Confirm the avatar descriptor uses the edited menu, Parameters asset, and FX controller.
Option B: Build a Continuous Hue Radial
Use this only when the shader property responds continuously across its range.
3B. Add the Float Parameter
Add the same parameter in both parameter assets:
Name: Color/Hue
Type: Float
Default: match the material's starting hue value
A synced Float uses 8 bits of VRChat custom parameter memory.
4B. Build the 1D Blend Tree
Create an FX layer named Color - Hue Radial, set its weight to 1, and create one state from a new Blend Tree. Make it the orange default state.
Configure the Blend Tree:
| Field | Value |
|---|---|
| Blend Type | 1D |
| Parameter | Color/Hue |
| Motion 1 | Hue_Min |
| Motion 1 threshold | 0 |
| Motion 2 | Hue_Max |
| Motion 2 threshold | 1 |
The layer does not need transitions because the default state continuously evaluates the Blend Tree. Scrub the Color/Hue Animator value and confirm the material follows the full range.
5B. Add the Radial Puppet
In the Expressions Menu:
- Add a control named
Hue. - Set its type to Radial Puppet.
- Assign
Color/Hueas its radial parameter. - Confirm the descriptor references the edited assets.
Saved, Synced, and Defaults
| Setting | Use it when | Check |
|---|---|---|
| Default | The avatar needs a predictable reset value | Match the material and orange default FX state |
| Saved | The wearer expects the selected hue to persist | Disable temporarily while testing a changed default |
| Synced | Remote players need to see the color | Include its 1-bit Bool or 8-bit Float cost in parameter memory |
VRChat uses puppet sync while a synced Radial Puppet is open and returns that parameter to playable sync after the puppet closes.
Match PC and Mobile Versions
The mobile avatar may need a different shader and platform-specific clips.
| Item | PC version | Mobile version |
|---|---|---|
| Parameter position | Keep unchanged | Same list position |
| Parameter type | Bool or Float | Same type |
| Default value | Chosen starting hue | Same visible starting result |
| Animation binding | PC shader property | Equivalent mobile shader property |
| Menu meaning | Hue Shift or Hue | Same meaning |
VRChat synchronizes custom parameters between platform versions by list position and type rather than parameter name. Use the same Expression Parameters asset across versions when possible.
If the mobile shader has no equivalent hue input, keep the parameter in the shared list and omit the mobile animation binding. Do not shift later parameters into different positions.
Test Matrix
Test a private upload before publishing the avatar.
| Test | Expected result |
|---|---|
| Avatar loads after reset | Material matches the configured default |
| Default clip previews | Only the intended hue property is recorded |
| Shifted or maximum clip previews | Only the intended mesh area changes |
| Toggle turns on | Shifted hue appears |
| Toggle turns off | Default hue returns |
Radial moves to 0 |
Minimum clip result appears |
| Radial moves through the middle | Hue changes continuously |
Radial moves to 1 |
Maximum clip result appears |
| Puppet closes | Selected radial value remains active |
| Saved parameter survives a reload | Selected value persists |
| Synced parameter is viewed remotely | Other players see the selected hue |
| PC and mobile versions are viewed | Both use equivalent behavior or an intentional mobile fallback |
Troubleshooting
Help! The menu changes but the material does not.
Confirm the menu control, Expression Parameters asset, FX parameter, and Animator condition or Blend Tree all use the same parameter name and type. Then preview the clips to verify their property bindings.
Help! The clip changes transforms or other avatar features.
Open the clip in the Animation window and remove every unintended binding. A hue clip should contain only the renderer material property required for the color change.
Help! The toggle turns on but cannot return to default.
Add the reverse transition from Hue Shifted to Hue Default with the Bool condition set to false. Disable Has Exit Time on both transitions.
Help! The radial snaps instead of blending.
Confirm the state contains a 1D Blend Tree with endpoint clips at thresholds 0 and 1. Two ordinary Animator states with threshold transitions create discrete changes instead.
Help! The color travels through unexpected shades.
Check whether the clips animate a dedicated hue scalar or an ordinary Color property. Color-component interpolation between two endpoints is not the same as rotating around a shader's hue control.
Help! The avatar starts with a previously selected hue.
The parameter may be Saved. Disable Saved while verifying a new default, reset the avatar, and align the Expression Parameter default with the material's starting value.
Help! Other players cannot see the hue change.
Enable Synced for the custom parameter and confirm the uploaded avatar uses the edited Expression Parameters asset. Test with a second client or observer rather than only a local mirror.
Help! The hue works on PC but not on mobile.
Inspect the mobile material and shader. The mobile version needs an equivalent animatable property and its own clips bound to that property; a PC-only shader binding cannot control a property the mobile shader does not expose.
Official References
- VRChat Expressions Menu and Controls
- VRChat Animator Parameters
- VRChat Playable Layers
- VRChat Per-Platform Avatar Overrides
- Unity Manual: Animation Clips
- Unity Manual: Using the Animation View
- Unity Manual: 1D Blending
Related Avatar Guides
- Control Avatar Colors with RGB Radial Puppets
- Select Avatar Materials with a Radial Puppet
- Swap Avatar Materials from the Expressions Menu
- Save Avatar Toggle States
- VRChat Quest Compatibility Checklist
Topics: VRChat avatar hue shift, material animation, FX Animator, Radial Puppet