Your own pickup

Hold pens through any pickup system instead of VRChat's, with three calls, and keep drawing on every platform.

Updated 2026-10-22

A pen or eraser does not need VRChat's pickup. Its holding field picks what holds it:

holding What holds it
VrcPickup The VRCPickup on the same object: picking it up holds it, its Use draws, R on desktop and the holding hand's upper face button in VR undo. The default
Custom Your code. VRChat's pickup events are ignored, so a VRCPickup may stay on the object or go

Three calls

With holding set to Custom, tell the pen what your system already knows:

Call When
SetHeld(true) The local player took it
SetUse(true) They pressed Use
SetUse(false) They let go of Use
Undo() They asked to undo their newest stroke
SetHeld(false) They put it down

Call them on the client of the player holding it; every other client hears the ink through the network as usual. A press made before SetHeld(true) does not count, and Use already down when the pen is taken has to be let go before it draws, so the trigger that grabbed a pen never also starts a stroke.

Where it still draws by itself

Holding is yours; where the ink goes stays the pen's. In VR it draws from its tip, so move the pen object with the hand as your pickup already does. On desktop and phones it draws from the player's view, so your pickup does not need to aim it at all, or from the tip as in VR when desktopAim is Tip, for a pickup that carries it in the hand.

An adapter

Most pickup systems raise events. A small behaviour beside the pen forwards them:

public class PenGrip : UdoniteBehaviour
{
    public Pen pen;

    public void OnGrabbed() => pen.SetHeld(true);
    public void OnReleased() => pen.SetHeld(false);
    public void OnUseDown() => pen.SetUse(true);
    public void OnUseUp() => pen.SetUse(false);
    public void OnAlternate() => pen.Undo();
}

Wire those to your system's events, set the pen's holding to Custom, and nothing else changes: ink styles, boards, erasing and the late-joiner copy all work the same.

Something went wrong Reload