Trigger Paired Avatar Animations with Contacts
Two compatible avatars can use matching Contact Sender and Contact Receiver tags to activate an animation. The receiver writes an Animator parameter when the matching contact enters its volume, and that parameter controls the avatar's animation state.
This setup adds a user-controlled opt-in toggle. The pose only activates when the wearer enables Pair Animation and the matching contact is present.
Give both avatar setups the same case-sensitive custom tag, then gate the receiver parameter with a menu toggle.
- Add a Contact Sender to one avatar and a Contact Receiver to the compatible avatar.
- Use the same custom Collision Tag on both components.
- Require both
PairModeEnabledandPairContactbefore entering the animation.
The tag identifies a compatible Contact setup, not a verified VRChat user ID. Any avatar using the same case-sensitive tag can match the receiver. Use the menu toggle as the wearer's explicit opt-in control.
Video Walkthrough
Use akalink's video for the Unity demonstration, then compare the project against the current component and Animator fields below.
Creator: akalink
Video: VRChat Avatar Dynamics Tutorial: Couples Animations
How the Pair Trigger Works
Avatar A: Contact Sender
Collision Tag = PairPoseDemo
│
│ matching volume overlap
▼
Avatar B: Contact Receiver
Collision Tag = PairPoseDemo
Parameter = PairContact
│
▼
Action Animator
PairModeEnabled = true
PairContact = true
│
▼
Paired pose animation
For a reciprocal interaction, each avatar needs both roles: a Sender that the other avatar can detect and a Receiver that drives its own animation.
| Avatar | Component | Result |
|---|---|---|
| Avatar A | Sender A + Receiver A | Signals Avatar B and controls Avatar A's pose |
| Avatar B | Sender B + Receiver B | Signals Avatar A and controls Avatar B's pose |
Contacts detect volume overlap and set parameters. They do not align the two player positions, rotate players toward each other, or synchronize the timing of two separate animation clips. Build both clips around a known relative position and expect manual alignment in the instance.
Plan the Two Parameters
Use one synced opt-in parameter and one receiver-driven parameter:
| Parameter | Type | Where it is defined | Purpose |
|---|---|---|---|
PairModeEnabled |
Bool | FX/Action Animator and VRC Expression Parameters | Wearer's menu-controlled permission |
PairContact |
Bool | Action Animator only | Contact Receiver output |
A Contact Receiver parameter does not need to be added to the VRC Expression Parameters asset. The menu toggle does need an Expression Parameters entry because the Expressions Menu controls it.
PairModeEnabled uses one bit of synced expression-parameter memory.
Create the Opt-In Menu Toggle
In the avatar's VRC Expression Parameters asset:
- Add
PairModeEnabled. - Set its type to Bool.
- Choose the default value deliberately;
falsekeeps the pair animation disabled when the avatar loads. - Leave it synced if other users should see the resulting menu-controlled state consistently.
In the Expressions Menu, add a Toggle control:
| Menu field | Value |
|---|---|
| Name | Pair Animation |
| Type | Toggle |
| Parameter | PairModeEnabled |
| Value | 1 |
This menu control does not trigger the pose by itself. It only allows the contact condition to activate it.
Configure the Contact Sender
Add a VRC Contact Sender to a child GameObject positioned at the intended interaction point.
| Sender field | Setup |
|---|---|
| Root Transform | The transform the volume should follow, or blank to use the component's GameObject |
| Shape Type | Sphere, Capsule, or Box based on the interaction area |
| Radius / Height / Size | Fit the visible interaction point without covering unrelated body areas |
| Position / Rotation | Align the contact volume in the Scene view |
| Local Only | Off when the sender must participate in the paired avatar interaction |
| Collision Tags | The shared custom tag, such as PairPoseDemo |
Collision tags are case-sensitive. PairPoseDemo and pairposedemo do not match. VRChat allows up to 16 tags on one Contact and recommends PascalCase for custom tags.
Configure the Contact Receiver
Add a VRC Contact Receiver to the partner avatar's corresponding interaction point.
| Receiver field | Setup |
|---|---|
| Root Transform | The transform the receiver volume should follow |
| Shape Type | Match the required interaction area |
| Allow Self | Off |
| Allow Others | On |
| Local Only | Off for the shared paired-avatar setup |
| Collision Tags | Exactly the same custom tag as the Sender |
| Receiver Type | Constant |
| Parameter | PairContact |
| Value | 1 |
With Constant, PairContact remains true while at least one matching Sender is present and returns to false when none are detected. This makes the animation exit condition predictable.
Use OnEnter only when the Animator should receive a one-frame pulse. For an animation that should remain active during overlap, Constant is the direct fit.
Build the Action Layer
Use the Action Playable Layer for a full-body pose. VRChat's Action layer is intended for transform animations that override the character, but the layer has zero weight by default. It must be blended up for the pose and back down afterward.
Create these states:
Entry
└── Pair Idle
├── Enable Action Weight
│ └── Pair Pose
│ └── Disable Action Weight
│ └── Pair Idle
└────────────────────────────────────────
Pair Idle → Enable Action Weight
Use both transition conditions:
PairModeEnabled == true
PairContact == true
Disable Has Exit Time. Both conditions must be true at the same time.
Enable Action Weight
Add a VRC Playable Layer Control behavior:
| Field | Value |
|---|---|
| Layer | Action |
| Goal Weight | 1 |
| Blend Duration | Short blend appropriate for the pose |
Transition to Pair Pose after the weight state has run.
Pair Pose
Assign the avatar's matching pose clip. The clip should contain only the transforms the pose is meant to control.
Exit to Disable Action Weight when either permission or contact ends. Unity transitions combine multiple conditions with AND, so use two separate exit transitions:
PairModeEnabled == false
PairContact == false
Either transition can leave the pose.
Disable Action Weight
Add another VRC Playable Layer Control:
| Field | Value |
|---|---|
| Layer | Action |
| Goal Weight | 0 |
| Blend Duration | Match the desired release blend |
Return to Pair Idle after the layer has blended down.
Control Tracking During the Pose
If the animation must control the head, hands, hip, or feet, add VRC Animator Tracking Control to the pose entry state and set only those body parts to Animation. Add a reset state that returns the same body parts to Tracking when the pose ends.
Tracking Control values persist until another state changes them. Omitting the reset can leave hands or other tracked body parts under animation control after the paired pose has finished.
| Body area | Use Animation when | Restore Tracking when |
|---|---|---|
| Head | The clip authors the head pose | The paired pose exits |
| Left / Right Hand | The clip fixes hand placement | The paired pose exits |
| Hip / Feet | A full-body clip controls them | The paired pose exits |
| Eyes / Eyelids | The clip intentionally controls them | Normal eye movement should resume |
| Mouth / Jaw | The clip intentionally suppresses visemes | Normal voice-driven visemes should resume |
Align the Pair
The two animation clips need matching reference positions:
- Author both avatars in the same scene using a shared origin.
- Place the avatar roots at the intended distance and facing direction.
- Animate each avatar's pose against that fixed reference.
- Position the Sender and Receiver volumes where the two avatars meet.
- In VRChat, have both players stand at the authored spacing before enabling the interaction.
Do not animate the avatar root to move the player capsule into position. The contact system supplies a trigger, not player locomotion or a shared constraint.
Test Both Avatars
Run every row with both avatars present:
| Test | Expected result |
|---|---|
| Both toggles off | Neither pose activates |
| Avatar A enabled, Avatar B disabled | Only Avatar A is eligible to pose |
| Both enabled but contacts separated | Both remain idle |
| Matching contacts overlap | Each enabled avatar enters its matching pose |
| One wearer disables the menu toggle | That avatar exits immediately |
| Contacts separate | Constant receiver resets and the pose exits |
| Non-matching custom tag enters | No parameter change |
| Same avatar touches its own receiver | No activation because Allow Self is off |
| Pose exits | Action weight returns to zero and tracking returns to Tracking |
| Third avatar copies the tag | The receiver can match it; the tag is not identity verification |
Troubleshooting
Help! The two Contacts overlap but nothing happens.
Compare the Collision Tags character by character because they are case-sensitive. Then confirm the Receiver has Allow Others enabled, uses PairContact, and the Animator contains a Bool parameter with the same name.
Help! The pose activates when I touch my own avatar.
Turn off Allow Self on the Contact Receiver. Keep Allow Others enabled so the partner avatar's Sender can still match it.
Help! Enabling the menu toggle immediately starts the pose.
Check the transition from Pair Idle. It must require both PairModeEnabled == true and PairContact == true, with Has Exit Time disabled.
Help! The animation stops as soon as the Contact enters.
Use the Constant Receiver Type for a pose that should remain active during overlap. OnEnter sets the receiver parameter for one frame and then resets it.
Help! The Action animation is active but has no visible effect.
The Action Playable Layer starts at zero weight. Confirm the entry state runs VRC Playable Layer Control with Action selected and Goal Weight set to 1 before the pose state.
Help! My hands remain locked after the pose ends.
Add a reset state with VRC Animator Tracking Control and return every body part changed by the pose to Tracking. Tracking Control persists until another state changes it.
Help! The avatars animate but do not line up.
Contacts only detect an overlap and set the parameter. Recheck the shared authoring origin, facing direction, root spacing, and the world-space placement players use before activating the pair.
Help! An unexpected avatar can trigger the interaction.
Any Sender with the same custom tag can match the Receiver. Change the shared tag on both intended avatars and keep the opt-in menu toggle off when the wearer does not want the interaction available.
Official VRChat References
Continue with Avatar Dynamics
- Use Contact Senders, Receivers, and PhysBone Parameters
- Build Hold-to-Activate Avatar Contacts
- Toggle Avatar Props with a PhysBone Grab Handle
- Test Avatar Dynamics at Four Levels
- Avatar Optimization Checklist
- Avatar Creation Guides
Topics: Contacts, paired animations, Action layer, avatar parameters