[VRChat] Fall Recovery and Checkpoints: Returning to the Last Platform

Created: 2026-05-22Last updated: 2026-09-09

From when standard respawn is enough, to a mechanism that returns players to their last checkpoint. Covers watching height, resetting velocity, and writing it so it can't loop forever.

Build an obstacle-course world and what happens when you fall becomes a problem.

Left to the standard setting, you're returned to the spawn point. Fall after a five-minute climb and you start over. Nobody keeps playing through that.

This article builds a mechanism that returns you to the last platform you passed. It also sorts out when to use the standard mechanism instead.

A fallen player being returned to a platform with a flag

What You'll Learn

  • When to use standard recovery versus your own checkpoints
  • Two ways to detect a fall
  • What to do about falling again right after being returned
  • The condition that prevents an endless respawn loop

Start from having tried building a teleporter and detecting areas with triggers.

Sponsored


Where standard recovery is enough, and where it isn't

VRChat ships with a mechanism for returning you after a fall: Respawn Height in the Scene Descriptor.

Standard recovery always returns to the spawn point; checkpoints return to the last platform

Fall below that height and you're returned to the spawn point. It works from a setting alone, so it's often enough on its own.

  • A flat room world → standard is enough
  • An exhibition or social world → standard is enough
  • A world with a long route → you want to resume partway

The third is where checkpoints become necessary. Obstacle courses, escape games, exploration worlds. They prevent "after all that climbing."

What you build is a combination of two things.

  1. Record on passing: every time someone passes through a detection volume on a platform, remember it as "the last platform"
  2. Return on falling: once they drop below a set height, move them to the remembered place

Both are built from mechanisms covered in earlier articles.

Sponsored

Hands-On: Build a checkpoint return

Line up three platforms as a staircase and return players to the last one they passed when they fall.

1. Place the platforms and checkpoints

Place the following in a scene with a floor.

NameHow to make it, and settings
Step0Cube. (0, 0.5, 3), Scale (2, 0.2, 2)
Step1Cube. (3, 1.5, 5), Scale (2, 0.2, 2)
Step2Cube. (6, 2.5, 7), Scale (2, 0.2, 2)
Three platforms rising step by step

The three platforms rise gradually as they extend into the distance.

On each, place a detection volume for recording and a return position.

NameParentSettings
Checkpoint0Child of Step0Create Empty. Local Position (0, 1, 0). Box Collider (Is Trigger on, Size (2, 2, 2))
Checkpoint1Child of Step1Same
Checkpoint2Child of Step2Same

Making them children of the platforms means the checkpoints move along when you move a platform.

2. Write the script that holds the record

First, build the side that remembers "which platform was last." Create CheckpointManager with "Create Empty" at (0, 0, 0).

Create CheckpointManager in Assets/Scripts.

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;

[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class CheckpointManager : UdonSharpBehaviour
{
    [SerializeField] private Transform defaultPoint;   // The first return point
    [SerializeField] private float fallLimitY = -3f;   // Below this counts as falling

    private Transform currentPoint;
    private VRCPlayerApi localPlayer;

    private void Start()
    {
        localPlayer = Networking.LocalPlayer;
        currentPoint = defaultPoint;
    }

    // Called from the checkpoint side
    public void SetCheckpoint(Transform point)
    {
        if (point == null) return;
        currentPoint = point;
        Debug.Log("[Checkpoint] recorded: " + point.name);
    }

    private void Update()
    {
        if (!Utilities.IsValid(localPlayer)) return;

        // Only compares height. Cheap work
        if (localPlayer.GetPosition().y > fallLimitY) return;

        Respawn();
    }

    private void Respawn()
    {
        Transform target = currentPoint != null ? currentPoint : defaultPoint;
        if (target == null) return;

        localPlayer.TeleportTo(target.position, target.rotation);
        localPlayer.SetVelocity(Vector3.zero);   // Kill the falling momentum
        Debug.Log("[Checkpoint] returned to: " + target.name);
    }
}

Fall detection uses Update. Running every frame may worry you, but all it does is compare one person's height, so the cost is tiny. It's more reliable than trigger-based detection, with no risk of being leapt over by a teleport.

Networking.LocalPlayer is fetched once in Start and held in a variable. That's lighter than re-fetching every frame.

3. Write the checkpoint side

Now the side that reports passage. Create CheckpointTrigger.

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;

[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class CheckpointTrigger : UdonSharpBehaviour
{
    [SerializeField] private CheckpointManager manager;
    [SerializeField] private Transform respawnPoint;   // Return position. Empty means this object

    public override void OnPlayerTriggerEnter(VRCPlayerApi player)
    {
        if (!player.isLocal) return;   // Ignore if the person passing isn't me
        if (manager == null) return;

        manager.SetCheckpoint(respawnPoint != null ? respawnPoint : transform);
    }
}

The isLocal check is in there. You don't want your record overwritten when someone else passes through.

Leaving respawnPoint empty returns you to the checkpoint's own position. Since it sits slightly above the platform, that works as-is.

4. Assign it and confirm

Add a Udon Behaviour to CheckpointManager, set the spawn point object as Default Point, and -3 as Fall Limit Y.

Add a Udon Behaviour to each of Checkpoint0 through Checkpoint2, set CheckpointTrigger, and drag CheckpointManager into Manager.

Press Play and try it.

ActionExpected result
Step onto Step0Console shows recorded: Checkpoint0
Fall from thereYou return above Checkpoint0
Climb to Step2, then fallYou return above Checkpoint2, not to the beginning
Right after returningYou're standing there (you don't fall again)

The third row is the point of this mechanism. Progress moves your restart point along with you.

The return point goes above the line

One accident comes with this mechanism: an endless respawn loop.

Recording a checkpoint, then returning there on a fall

When the return height is below the height that counts as falling (fallLimitY), this happens.

  1. You fall
  2. You're returned
  3. The return position is still below the line
  4. You're judged to have fallen again
  5. Repeat forever

The screen flickers and you can't move.

Preventing it is simple. Always put the return point above the line. In this example the lowest one, Checkpoint0, sits around Y=1.5 while fallLimitY is -3, which is plenty of separation.

Also, don't forget to zero the velocity right after returning. Without SetVelocity(Vector3.zero), you're returned still carrying falling momentum and cross the line again the next instant. Same endless loop.

When picking the detection height, aim for several meters below the lowest checkpoint.

Sponsored

Common Pitfalls

  • It doesn't return you → Is CheckpointManager's Fall Limit Y too low? Is it set to a value you never reach by falling off a platform?
  • The screen flickers and you can't move → An endless respawn loop. Review the return height and the detection height
  • You return and fall againSetVelocity(Vector3.zero) is missing
  • Nothing gets recorded → Check that the checkpoint's Collider has Is Trigger on, and that Manager is assigned
  • Someone else passing changes your record → The isLocal check is missing

Bonus: Good to Know Up Front

  • Keep the standard Respawn Height too: It's insurance for when this mechanism fails for some reason. Set it further below the detection height
  • Each person holds their own record: This code isn't synchronized, so checkpoints are held individually. For an obstacle course, that's the correct behavior
  • The return point can carry a facing too: Adjusting the checkpoint's Rotation sets which way you face on return. Facing them toward the next section is a kindness
Actually falling and being returned
  • Signal the return: A sound or a short display makes it clear that you were returned. The sound handling in toggling with a button works here
  • Checkpoints don't have to go backwards: You can build it so passing an earlier checkpoint after progressing doesn't roll the record back. Give them numbers and record only the higher one

Summary

Checkpoints are a combination of two parts.

  • Record on passing (trigger + isLocal)
  • Return on falling (height watch + TeleportTo)
  • Kill momentum with SetVelocity(Vector3.zero) right after returning
  • Always put the return point above the fall-detection line

The question to ask after building it is: "Is the return position above the line?" Miss that and you get an endless respawn loop.

To use movement mechanisms further, go to building a teleporter. To expand area detection, go to detecting areas with triggers.

VRChat Notes in this section63