Your own pickup
Hold pens through any pickup system instead of VRChat's, with three calls, and keep drawing on every platform.
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.