Set Up Twist Bones on a VRChat Avatar

Twist bones help distribute rotation through a skinned limb instead of concentrating all deformation at one joint. If the avatar already contains weighted twist bones, a VRChat Rotation Constraint can make each twist bone follow an appropriate source transform at runtime.

Recommended setup

Preserve the imported armature, drive only the existing helper bone, and test the result with extreme wrist and limb rotations before upload.

  1. Confirm the twist bone already influences the skinned mesh.
  2. Add a VRChat Rotation Constraint and assign the intended source transform.
  3. Solve in local space and exclude rotation axes the helper bone should not inherit.
  4. Activate the constraint to preserve the current offset.
  5. Check IK, deformation, constraint depth, and both platform builds.
Use VRChat constraints on avatars

VRChat recommends its own constraints instead of Unity constraints for avatars. Unity constraints are converted when the avatar loads in VRChat, but using VRChat constraints directly gives a more accurate editor preview and performance-rank calculation.

What a Twist-Bone Constraint Can Fix

A twist-bone setup can improve deformation when rotating a wrist, forearm, ankle, or another long limb section. It is useful when the model already has:

  • a helper bone positioned along the limb;
  • vertex weights assigned to that helper bone; and
  • a known source bone whose rotation it should partially follow.

A constraint does not create skin weights or repair poor topology. If the mesh is not weighted to the twist bone, configure the rig in Blender or another modelling application before returning to Unity.

Check the Imported Rig First

  1. Select the model asset in the Project window.
  2. Open the Rig tab and confirm the intended animation type.
  3. For a Humanoid avatar, open Configure and confirm the required humanoid bones are mapped correctly.
  4. Leave twist bones and other helper bones out of humanoid mapping slots unless the model's rig documentation explicitly requires otherwise.
  5. Check that the mapped Hips remains an ancestor of the humanoid hierarchy.
  6. Apply the Avatar Descriptor's T-Pose and rotate the limb while inspecting the mesh.

VRChat notes that prop-placement bones, twist bones, and other helper children can confuse IK in some hierarchies. Keep helpers outside the mapped humanoid chain rather than inserting one between required mapped bones.

Add a VRChat Rotation Constraint

The VRCRotationConstraint component changes a target transform's rotation to match one or more source transforms.

1. Add the component

Select the twist bone and add VRC Rotation Constraint. You can instead place the component on a separate object and assign the twist bone under Target Transform, but a direct component is easier to inspect for a single helper bone.

2. Assign the source

In Sources, add the transform that carries the rotation the twist bone needs to follow. Use the source intended by the avatar's rig design rather than guessing from its name alone.

Each source has its own weight, and the constraint also has an overall Weight. Begin with the rig author's intended values when they are available. Otherwise, adjust conservatively while comparing the rest pose, a 90-degree turn, and the most extreme rotation the avatar will reach.

3. Use local-space solving

Enable Solve In Local Space when the helper should follow rotation relative to its parent in the armature. VRChat documents local solving specifically for constraint-driven bone chains that follow a real limb.

Under Freeze Rotation Axes, exclude axes that the twist bone should not inherit. The correct axis depends on how the model was exported, so use the bone's local axes and deformation result rather than assuming every armature twists around the same lettered axis.

4. Preserve the rest offset

With the avatar in its intended rest pose, use Activate Constraint. VRChat's component saves the current offset, activates the constraint, and locks its rest and offset values.

Use Zero Constraint only when the target should match the source without preserving the current offset. It resets the offset before activating and locking the constraint.

5. Confirm that it is running

The constraint affects its target only when:

  • Is Active is enabled;
  • the component is enabled;
  • its GameObject is active; and
  • Lock is enabled.

If Lock is disabled, the component recalculates its rest and offset values as the target moves instead of taking control of the transform.

Test the Deformation

Test one side before copying the setup to the mirrored limb.

Test pose What to inspect
Rest or T-Pose The helper bone should not snap or change the silhouette
Wrist rotated inward and outward Rotation should spread through the forearm without a sharp collapse
Elbow fully bent The helper should not pull vertices across the joint
Arm raised and lowered Shoulder and elbow IK should remain stable
Gesture or action animation Animated transforms and the constraint should not fight

Do not judge the setup from the Scene view alone. Test the Avatar Descriptor's playable layers and complete a VRChat test build so the same runtime constraint system used by the client is evaluated.

Original Video Companion

The original Iconoclass video remains useful for seeing the deformation problem and an older Unity setup. Component names and inspector controls have changed, so use the current VRChat constraint workflow above for new avatars.

Performance and Platform Checks

VRChat counts every enabled or disabled constraint on an avatar. It also measures Constraint Depth, which is the longest chain of constraints that depend on one another. A left and right twist constraint that independently read their limb sources do not automatically form one long dependency chain.

VRChat also counts bones in the avatar performance rank. Check the current PC and mobile performance tables after adding helper bones or constraints, especially for an avatar that is already near a target rank.

For the most accurate constraint-depth calculation, use VRChat constraints exclusively. The SDK control panel can offer an Auto Fix to convert Unity constraints to their VRChat equivalents.

Upload Checklist

  1. Confirm there are no missing source or target transforms.
  2. Test the rest pose before testing animated poses.
  3. Check both arms or legs through their full useful rotation range.
  4. Test crouching, locomotion, gestures, and full-body tracking if the avatar supports them.
  5. Review constraint count, constraint depth, and bone count in the SDK avatar statistics.
  6. Resolve rig and hierarchy validation messages in the SDK Builder.
  7. Test PC and mobile versions separately when both are published.
The twist bone snaps when I activate the constraint.

Return the avatar to its intended rest pose and use Activate Constraint so the current relationship is stored as an offset. Check the source transform and use Zero Constraint only if a zero offset is intentional.

The constraint is active, but the twist bone does not move.

Confirm the component and GameObject are enabled, Is Active is checked, Lock is enabled, and the source and target references are valid. Also check that the overall weight and source weight are above zero.

The bone rotates around the wrong axes.

Inspect the twist bone's local axes, enable Solve In Local Space, and exclude unwanted axes under Freeze Rotation Axes. Imported armatures do not all use the same local axis for limb twist.

The bone moves correctly, but the mesh does not improve.

The constraint only rotates a transform. Inspect the Skinned Mesh Renderer and the model's vertex weights; the affected vertices must already be weighted to the twist bone.

The arms behave differently in VRChat than in the Unity preview.

Check the Humanoid mapping and hierarchy, then test with the Avatar Descriptor's playable layers and a VRChat test build. Helper bones inserted into the mapped humanoid chain can interfere with IK.

The SDK reports a high constraint depth.

Look for constraints that target bones used as sources by later constraints. Shorten unnecessary dependency chains and convert Unity constraints with the SDK Auto Fix so the depth can be calculated accurately.

I copied the component to the other arm and it twists backward.

Assign the mirrored limb's own source and target, then activate the copied constraint in the rest pose. Mirrored bones may have different local-axis orientations, so verify the frozen axes independently.

Official References

Related Guides

Topics: avatar rigging, twist bones, rotation constraints, deformation, performance