【VRChat】Creating Door Gimmicks: Synced Automatic and Manual Door Implementation

Created: 2025-12-19

Implementation methods for doors as fundamental dynamic objects. Automatic doors that open when approached, manual doors that open/close on click, animation integration and network synchronization.

Overview

Doors are fundamental architectural elements that divide spaces and control player movement, making them an ideal gimmick as a first step toward bringing interactivity to your world. When doors open automatically or open/close through player actions, the world gains significantly more immersion.

This article explains the basics of animation, which is essential for implementing door gimmicks, and provides step-by-step instructions for creating the following two practical door types:

  1. Synced Automatic Door: Opens automatically when a player approaches and closes when they leave. The state is synchronized across all players.
  2. Synced Manual Door: Opens/closes when a doorknob or similar is clicked (Interact), with the state synchronized across all players.

Step 1: Preparing the Door and Animations in Unity Editor

First, prepare the door model and animations to be controlled by UdonSharp.

1. Door GameObject Structure

  • To make a rotating door work correctly, use a parent-child relationship for GameObjects. First, create an empty GameObject and name it "Door_Pivot." This becomes the door's rotation axis (hinge).
  • Next, make the 3D door model a child object of "Door_Pivot." Adjust the local coordinates of the door model so that the rotation axis is at the edge of the model.
  • By doing this, simply rotating "Door_Pivot" will make the door open and close realistically.

2. Creating Open/Close Animations

  • With the Door_Pivot object selected, open the Animation window from Unity's menu: [Window] > [Animation] > [Animation].
  • Press the "Create" button and create a new animation clip. Save it first as "Door_Open."
  • Press the record button (red circle) to start recording the animation.
    • At frame 0, register a keyframe for the Door_Pivot's Transform > Rotation property in its initial state (e.g., Y=0).
    • At frame 60 (1 second later), change the Rotation to the door's open state (e.g., Y=90) and register a keyframe.
  • Stop recording. You now have an animation of the door opening.
  • Follow the same procedure to create a "Door_Close" animation (frame 0 is Y=90, frame 60 is Y=0).

3. Animator Controller Setup

  • Right-click in the Project window and select [Create] > [Animator Controller], creating one named "Door_Animator."
  • Double-click the created Door_Animator to open the Animator window.
  • Drag & drop the "Door_Open" and "Door_Close" animation clips from the Project window into the Animator window.
  • In the "Parameters" tab on the left side of the Animator window, click the "+" button and select "Trigger" to create two triggers named "Open" and "Close."
  • Draw an arrow (transition) from the Entry state to Door_Close. This sets the door to be closed by default.
  • Draw a transition from Door_Close to Door_Open, select that transition, and set "Open" trigger in Conditions in the Inspector.
  • Draw a transition from Door_Open to Door_Close and set "Close" trigger in Conditions.
  • Finally, add an Animator component to the Door_Pivot object and assign the created Door_Animator to the Controller field.

Now you're ready to play the corresponding animation by calling the "Open" or "Close" trigger from UdonSharp.

Pattern 1: Synced Automatic Door

A door that opens when a player approaches and closes when they leave. When someone approaches, the door opens in all players' views through synchronization.

Trigger Setup

  • Add a Box Collider component to the Door_Pivot object.
  • Adjust the size of the Box Collider to cover the area where you want to detect a player approaching the door (the space in front of and behind the door).
  • In the Box Collider's Inspector, check the Is Trigger property. This makes it function as a sensor that detects entry rather than a physical wall.

Script: SyncedAutoDoor.cs

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;

public class SyncedAutoDoor : UdonSharpBehaviour
{
    [Tooltip("Assign the Animator for the door to control.")]
    public Animator doorAnimator;

    // Sync whether someone is inside the trigger
    [UdonSynced]
    private bool isSomeoneInside = false;

    // Locally count players inside the trigger
    private int localPlayerCount = 0;

    // Called when a player enters the trigger area
    public override void OnPlayerTriggerEnter(VRCPlayerApi player)
    {
        // Only process if the local player entered
        if (!player.isLocal) return;

        localPlayerCount++;
        // If you're the first one entering, take ownership and update state
        if (localPlayerCount == 1)
        {
            Networking.SetOwner(Networking.LocalPlayer, this.gameObject);
            isSomeoneInside = true;
            RequestSerialization();
            UpdateDoorState();
        }
    }

    // Called when a player exits the trigger area
    public override void OnPlayerTriggerExit(VRCPlayerApi player)
    {
        if (!player.isLocal) return;

        localPlayerCount--;
        // If you're the last one leaving, take ownership and update state
        if (localPlayerCount == 0)
        {
            Networking.SetOwner(Networking.LocalPlayer, this.gameObject);
            isSomeoneInside = false;
            RequestSerialization();
            UpdateDoorState();
        }
    }

    public override void OnDeserialization()
    {
        UpdateDoorState();
    }

    private void UpdateDoorState()
    {
        if (doorAnimator != null)
        {
            if (isSomeoneInside)
            {
                doorAnimator.SetTrigger("Open");
            }
            else
            {
                doorAnimator.SetTrigger("Close");
            }
        }
    }
}

Unity Setup

  1. Create SyncedAutoDoor.cs and assign it to the Udon Behaviour attached to the Door_Pivot object.
  2. Drag & drop the Animator component also attached to Door_Pivot into the Door Animator field.

Pattern 2: Synced Manual Door

A door that opens/closes when the door or doorknob is clicked.

Script: SyncedManualDoor.cs

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;

public class SyncedManualDoor : UdonSharpBehaviour
{
    [Tooltip("Assign the Animator for the door to control.")]
    public Animator doorAnimator;

    [UdonSynced]
    private bool isOpen = false;

    void Start()
    {
        UpdateDoorState();
    }

    public override void Interact()
    {
        Networking.SetOwner(Networking.LocalPlayer, this.gameObject);
        isOpen = !isOpen;
        RequestSerialization();
        UpdateDoorState();
    }

    public override void OnDeserialization()
    {
        UpdateDoorState();
    }

    private void UpdateDoorState()
    {
        if (doorAnimator != null)
        {
            if (isOpen)
            {
                doorAnimator.SetTrigger("Open");
            }
            else
            {
                doorAnimator.SetTrigger("Close");
            }
        }
    }
}

Unity Setup

  1. Create SyncedManualDoor.cs and assign it to the Udon Behaviour on the object you want players to click (the door itself, or a separate object created as a doorknob).
  2. Verify that the object has a Collider attached and that the Udon Behaviour's Interaction Text is set.
  3. Drag & drop the Animator component from the Door_Pivot object into the Door Animator field.

Summary

  • The core of door gimmicks is the integration of Animator Controller and UdonSharp. You call SetTrigger from UdonSharp to play animations.
  • Automatic doors use OnPlayerTriggerEnter/Exit and a Collider set as a trigger.
  • Manual doors use the Interact event.
  • In both patterns, by managing the open/close state with an [UdonSynced] variable and calling RequestSerialization() when the state changes, you can synchronize door movement across all players.

Doors are an ideal subject for learning the key elements of UdonSharp gimmick creation: animation, triggers, and synchronization. By applying this knowledge, you'll be able to create various dynamic objects such as moving floors and hidden passages.