Skip to content

Events

82 are written with override; 43 are recognized by name and argument types. Types are written in full; write a using and the short name works.

Forms written by overriding a base declaration

Section titled “Forms written by overriding a base declaration”
SyntaxName calledVariable that receives the argument
void InputDrop(bool value, VRC.Udon.Common.UdonInputEventArgs args)_inputDropinputDropBoolValue inputDropArgs
void InputGrab(bool value, VRC.Udon.Common.UdonInputEventArgs args)_inputGrabinputGrabBoolValue inputGrabArgs
void InputJump(bool value, VRC.Udon.Common.UdonInputEventArgs args)_inputJumpinputJumpBoolValue inputJumpArgs
void InputLookHorizontal(float value, VRC.Udon.Common.UdonInputEventArgs args)_inputLookHorizontalinputLookHorizontalFloatValue inputLookHorizontalArgs
void InputLookVertical(float value, VRC.Udon.Common.UdonInputEventArgs args)_inputLookVerticalinputLookVerticalFloatValue inputLookVerticalArgs
void InputMoveHorizontal(float value, VRC.Udon.Common.UdonInputEventArgs args)_inputMoveHorizontalinputMoveHorizontalFloatValue inputMoveHorizontalArgs
void InputMoveVertical(float value, VRC.Udon.Common.UdonInputEventArgs args)_inputMoveVerticalinputMoveVerticalFloatValue inputMoveVerticalArgs
void InputUse(bool value, VRC.Udon.Common.UdonInputEventArgs args)_inputUseinputUseBoolValue inputUseArgs
void Interact()_interact—
void MidiControlChange(int channel, int number, int value)_midiControlChangemidiControlChangeChannel midiControlChangeNumber midiControlChangeValue
void MidiNoteOff(int channel, int number, int velocity)_midiNoteOffmidiNoteOffChannel midiNoteOffNumber midiNoteOffVelocity
void MidiNoteOn(int channel, int number, int velocity)_midiNoteOnmidiNoteOnChannel midiNoteOnNumber midiNoteOnVelocity
void OnAsyncGpuReadbackComplete(VRC.SDK3.Rendering.VRCAsyncGPUReadbackRequest request)_onAsyncGpuReadbackCompleteonAsyncGpuReadbackCompleteRequest
void OnAvatarChanged(VRC.SDKBase.VRCPlayerApi player)_onAvatarChangedonAvatarChangedPlayer
void OnAvatarEyeHeightChanged(VRC.SDKBase.VRCPlayerApi player, float prevEyeHeightAsMeters)_onAvatarEyeHeightChangedonAvatarEyeHeightChangedPlayer onAvatarEyeHeightChangedPrevEyeHeightAsMeters
void OnContactEnter(VRC.Dynamics.ContactEnterInfo contactInfo)_onContactEnteronContactEnterContactInfo
void OnContactExit(VRC.Dynamics.ContactExitInfo contactInfo)_onContactExitonContactExitContactInfo
void OnControllerColliderHitPlayer(VRC.SDK3.ControllerColliderPlayerHit hit)_onControllerColliderHitPlayeronControllerColliderHitPlayerHit
void OnDeserialization(VRC.Udon.Common.DeserializationResult result)_onDeserializationonDeserializationResult
void OnDroneTriggerEnter(VRC.SDKBase.VRCDroneApi drone)_onDroneTriggerEnteronDroneTriggerEnterDrone
void OnDroneTriggerExit(VRC.SDKBase.VRCDroneApi drone)_onDroneTriggerExitonDroneTriggerExitDrone
void OnDroneTriggerStay(VRC.SDKBase.VRCDroneApi drone)_onDroneTriggerStayonDroneTriggerStayDrone
void OnDrop()_onDrop—
void OnImageLoadError(VRC.SDK3.Image.IVRCImageDownload result)_onImageLoadErroronImageLoadErrorIVRCImageDownload
void OnImageLoadSuccess(VRC.SDK3.Image.IVRCImageDownload result)_onImageLoadSuccessonImageLoadSuccessIVRCImageDownload
void OnInputMethodChanged(VRC.SDKBase.VRCInputMethod inputMethod)_onInputMethodChangedonInputMethodChangedInputMethod
void OnLanguageChanged(string language)_onLanguageChangedonLanguageChangedLanguage
void OnListAvailableProducts(VRC.Economy.IProduct[] products)_onListAvailableProductsonListAvailableProductsResult
void OnListProductOwners(VRC.Economy.IProduct product, string[] owners)_onListProductOwnersonListProductOwnersResult onListProductOwnersOwners
void OnListPurchases(VRC.Economy.IProduct[] products, VRC.SDKBase.VRCPlayerApi player)_onListPurchasesonListPurchasesResult onListPurchasesPlayer
void OnMasterTransferred(VRC.SDKBase.VRCPlayerApi newMaster)_onMasterTransferredonMasterTransferredNewMaster
bool OnOwnershipRequest(VRC.SDKBase.VRCPlayerApi requestingPlayer, VRC.SDKBase.VRCPlayerApi requestedOwner)_onOwnershipRequestonOwnershipRequestRequester onOwnershipRequestNewOwner
void OnOwnershipTransferred(VRC.SDKBase.VRCPlayerApi player)_onOwnershipTransferredonOwnershipTransferredPlayer
void OnPersistenceUsageUpdated()_onPersistenceUsageUpdated—
void OnPhysBoneGrabbed(VRC.Dynamics.PhysBoneGrabbedInfo physBoneInfo)_onPhysBoneGrabbedonPhysBoneGrabbedPhysBoneInfo
void OnPhysBonePosed(VRC.Dynamics.PhysBonePosedInfo physBoneInfo)_onPhysBonePosedonPhysBonePosedPhysBoneInfo
void OnPhysBoneReleased(VRC.Dynamics.PhysBoneReleasedInfo physBoneInfo)_onPhysBoneReleasedonPhysBoneReleasedPhysBoneInfo
void OnPhysBoneUnPosed(VRC.Dynamics.PhysBoneUnPosedInfo physBoneInfo)_onPhysBoneUnPosedonPhysBoneUnPosedPhysBoneInfo
void OnPickup()_onPickup—
void OnPickupUseDown()_onPickupUseDown—
void OnPickupUseUp()_onPickupUseUp—
void OnPlayerCollisionEnter(VRC.SDKBase.VRCPlayerApi player)_onPlayerCollisionEnteronPlayerCollisionEnterPlayer
void OnPlayerCollisionExit(VRC.SDKBase.VRCPlayerApi player)_onPlayerCollisionExitonPlayerCollisionExitPlayer
void OnPlayerCollisionStay(VRC.SDKBase.VRCPlayerApi player)_onPlayerCollisionStayonPlayerCollisionStayPlayer
void OnPlayerDataStorageExceeded(VRC.SDKBase.VRCPlayerApi player)_onPlayerDataStorageExceededonPlayerDataStorageExceededPlayer
void OnPlayerDataStorageWarning(VRC.SDKBase.VRCPlayerApi player)_onPlayerDataStorageWarningonPlayerDataStorageWarningPlayer
void OnPlayerDataUpdated(VRC.SDKBase.VRCPlayerApi player, VRC.SDK3.Persistence.PlayerData.Info[] infos)_onPlayerDataUpdatedonPlayerDataUpdatedPlayer onPlayerDataUpdatedInfos
void OnPlayerJoined(VRC.SDKBase.VRCPlayerApi player)_onPlayerJoinedonPlayerJoinedPlayer
void OnPlayerLeft(VRC.SDKBase.VRCPlayerApi player)_onPlayerLeftonPlayerLeftPlayer
void OnPlayerObjectStorageExceeded(VRC.SDKBase.VRCPlayerApi player)_onPlayerObjectStorageExceededonPlayerObjectStorageExceededPlayer
void OnPlayerObjectStorageWarning(VRC.SDKBase.VRCPlayerApi player)_onPlayerObjectStorageWarningonPlayerObjectStorageWarningPlayer
void OnPlayerParticleCollision(VRC.SDKBase.VRCPlayerApi player)_onPlayerParticleCollisiononPlayerParticleCollisionPlayer
void OnPlayerRespawn(VRC.SDKBase.VRCPlayerApi player)_onPlayerRespawnonPlayerRespawnPlayer
void OnPlayerRestored(VRC.SDKBase.VRCPlayerApi player)_onPlayerRestoredonPlayerRestoredPlayer
void OnPlayerSuspendChanged(VRC.SDKBase.VRCPlayerApi player)_onPlayerSuspendChangedonPlayerSuspendChangedPlayer
void OnPlayerTriggerEnter(VRC.SDKBase.VRCPlayerApi player)_onPlayerTriggerEnteronPlayerTriggerEnterPlayer
void OnPlayerTriggerExit(VRC.SDKBase.VRCPlayerApi player)_onPlayerTriggerExitonPlayerTriggerExitPlayer
void OnPlayerTriggerStay(VRC.SDKBase.VRCPlayerApi player)_onPlayerTriggerStayonPlayerTriggerStayPlayer
void OnPostSerialization(VRC.Udon.Common.SerializationResult result)_onPostSerializationonPostSerializationResult
void OnPreSerialization()_onPreSerialization—
void OnProductEvent(VRC.Economy.IProduct product, VRC.SDKBase.VRCPlayerApi player)_onProductEventonProductEventResult onProductEventPlayer
void OnPurchaseConfirmed(VRC.Economy.IProduct product, VRC.SDKBase.VRCPlayerApi player, bool purchasedNow)_onPurchaseConfirmedonPurchaseConfirmedResult onPurchaseConfirmedPlayer onPurchaseConfirmedPurchasedNow
void OnPurchaseConfirmedMultiple(VRC.Economy.IProduct product, VRC.SDKBase.VRCPlayerApi player, bool purchasedNow, int quantity)_onPurchaseConfirmedMultipleonPurchaseConfirmedMultipleResult onPurchaseConfirmedMultiplePlayer onPurchaseConfirmedMultiplePurchasedNow onPurchaseConfirmedMultipleQuantity
void OnPurchaseExpired(VRC.Economy.IProduct product, VRC.SDKBase.VRCPlayerApi player)_onPurchaseExpiredonPurchaseExpiredResult onPurchaseExpiredPlayer
void OnPurchasesLoaded(VRC.Economy.IProduct[] products, VRC.SDKBase.VRCPlayerApi player)_onPurchasesLoadedonPurchasesLoadedResult onPurchasesLoadedPlayer
void OnScreenUpdate(VRC.SDK3.Platform.ScreenUpdateData data)_onScreenUpdateonScreenUpdateData
void OnSpawn()_onSpawn—
void OnStationEntered(VRC.SDKBase.VRCPlayerApi player)_onStationEnteredonStationEnteredPlayer
void OnStationExited(VRC.SDKBase.VRCPlayerApi player)_onStationExitedonStationExitedPlayer
void OnStringLoadError(VRC.SDK3.StringLoading.IVRCStringDownload result)_onStringLoadErroronStringLoadErrorIVRCStringDownload
void OnStringLoadSuccess(VRC.SDK3.StringLoading.IVRCStringDownload result)_onStringLoadSuccessonStringLoadSuccessIVRCStringDownload
void OnVRCCameraSettingsChanged(VRC.SDK3.Rendering.VRCCameraSettings cameraSettings)_onVRCCameraSettingsChangedonVRCCameraSettingsChangedCamera
void OnVRCPlusMassGift(VRC.SDKBase.VRCPlayerApi gifter, int numGifts)_onVRCPlusMassGiftonVRCPlusMassGiftGifter onVRCPlusMassGiftNumGifts
void OnVRCQualitySettingsChanged()_onVRCQualitySettingsChanged—
void OnVideoEnd()_onVideoEnd—
void OnVideoError(VRC.SDK3.Components.Video.VideoError videoError)_onVideoErroronVideoErrorVideoError
void OnVideoLoop()_onVideoLoop—
void OnVideoPause()_onVideoPause—
void OnVideoPlay()_onVideoPlay—
void OnVideoReady()_onVideoReady—
void OnVideoStart()_onVideoStart—
void PostLateUpdate()_postLateUpdate—

Forms recognized by name and argument type

Section titled “Forms recognized by name and argument type”
SyntaxName calledVariable that receives the argument
void FixedUpdate()_fixedUpdate—
void LateUpdate()_lateUpdate—
void OnAnimatorIK(int layerIndex)_onAnimatorIKonAnimatorIKLayerIndex
void OnAnimatorMove()_onAnimatorMove—
void OnBecameInvisible()_onBecameInvisible—
void OnBecameVisible()_onBecameVisible—
void OnCollisionEnter(UnityEngine.Collision other)_onCollisionEnteronCollisionEnterOther
void OnCollisionEnter2D(UnityEngine.Collision2D other)_onCollisionEnter2DonCollisionEnter2DOther
void OnCollisionExit(UnityEngine.Collision other)_onCollisionExitonCollisionExitOther
void OnCollisionExit2D(UnityEngine.Collision2D other)_onCollisionExit2DonCollisionExit2DOther
void OnCollisionStay(UnityEngine.Collision other)_onCollisionStayonCollisionStayOther
void OnCollisionStay2D(UnityEngine.Collision2D other)_onCollisionStay2DonCollisionStay2DOther
void OnControllerColliderHit(UnityEngine.ControllerColliderHit hit)_onControllerColliderHitonControllerColliderHitHit
void OnDestroy()_onDestroy—
void OnDisable()_onDisable—
void OnEnable()_onEnable—
void OnJointBreak(float breakForce)_onJointBreakonJointBreakBreakForce
void OnJointBreak2D(UnityEngine.Joint2D brokenJoint)_onJointBreak2DonJointBreak2DBrokenJoint
void OnMouseDown()_onMouseDown—
void OnMouseDrag()_onMouseDrag—
void OnMouseEnter()_onMouseEnter—
void OnMouseExit()_onMouseExit—
void OnMouseOver()_onMouseOver—
void OnMouseUp()_onMouseUp—
void OnMouseUpAsButton()_onMouseUpAsButton—
void OnParticleCollision(UnityEngine.GameObject other)_onParticleCollisiononParticleCollisionOther
void OnParticleTrigger()_onParticleTrigger—
void OnPostRender()_onPostRender—
void OnPreCull()_onPreCull—
void OnPreRender()_onPreRender—
void OnRenderImage(UnityEngine.RenderTexture src, UnityEngine.RenderTexture dest)_onRenderImageonRenderImageSrc onRenderImageDest
void OnRenderObject()_onRenderObject—
void OnTransformChildrenChanged()_onTransformChildrenChanged—
void OnTransformParentChanged()_onTransformParentChanged—
void OnTriggerEnter(UnityEngine.Collider other)_onTriggerEnteronTriggerEnterOther
void OnTriggerEnter2D(UnityEngine.Collider2D other)_onTriggerEnter2DonTriggerEnter2DOther
void OnTriggerExit(UnityEngine.Collider other)_onTriggerExitonTriggerExitOther
void OnTriggerExit2D(UnityEngine.Collider2D other)_onTriggerExit2DonTriggerExit2DOther
void OnTriggerStay(UnityEngine.Collider other)_onTriggerStayonTriggerStayOther
void OnTriggerStay2D(UnityEngine.Collider2D other)_onTriggerStay2DonTriggerStay2DOther
void OnWillRenderObject()_onWillRenderObject—
void Start()_start—
void Update()_update—
SyntaxDescriptionErrorReasonAlternative
public void _start() and void Start()Give a method the name the runtime usesTUKI0001runtimeChange the method’s name
base.OnPlayerJoined(player)Call the base implementation from the overrideTUKI0101runtimeWrite only your own code without calling the base implementation (the base has none)
FamilyIf the name is wrongIf an argument type is wrong
Written with override (82)You get a CS0115 errorYou get a CS0115 error
Written by name and argument type (43)Supported. Never calledSupported. Never called

Events come in two families, differing both in where they are declared and in what checks their spelling.

Written with override (82)Recognized by name (43)
OriginRuntime eventsUnity messages
Where it is declaredThe base TsukimiBehaviourNowhere (you write it yourself)
Spelling checksThe C# compilerNothing does (Spelling checks)
Checking of parameter typesThe C# compilerNot performed
When it departs from the listA CS0115 errorIt becomes an ordinary method
Access modifierWritten with public overrideDoesn’t matter (private is still an event)
Return valueAs declared in the basevoid
Shape of the callA method matching a name and argument types from the list is given an entry-point name such as _start, and the runtime calls it by that name (not a C# virtual call)Same

The shortest form is Start.

using UnityEngine;
using Tsukimi;
public class EventsStart : TsukimiBehaviour
{
void Start()
{
Debug.Log(1); // => 1
}
}

Match the declaration the base already holds.

using UnityEngine;
using Tsukimi;
public class EventsInteract : TsukimiBehaviour
{
public override void Interact()
{
Debug.Log(2);
}
void Start()
{
Debug.Log(1); // => 1
}
}

With override, C# checks both the spelling and the argument types, so you get an error on the spot.

using UnityEngine;
using Tsukimi;
using VRC.SDKBase;
public class R_events_override_typo : TsukimiBehaviour
{
public override void OnPlayerJoind(VRCPlayerApi player)
{
Debug.Log(player.playerId);
}
}

The Update below takes one argument, so it isn’t an event; being private with nothing calling it, no instructions are generated either.

using UnityEngine;
using Tsukimi;
public class EventsNameMatchMiss : TsukimiBehaviour
{
private void Update(float delta)
{
Debug.Log(2);
}
void Start()
{
Debug.Log(1); // => 1
}
}

A method marked private is an event too.

using UnityEngine;
using Tsukimi;
public class EventsPrivateEvent : TsukimiBehaviour
{
private void LateUpdate()
{
Debug.Log(2);
}
void Start()
{
Debug.Log(1); // => 1
}
}

The runtime calls the program using the event name with its first letter lowercased and an _ prefixed (Start becomes _start; that name is the middle column of the table in the list).

That name is registered separately from the method name, so writing a method with the same spelling yourself registers it twice and produces a TUKI0001 error.

using UnityEngine;
using Tsukimi;
public class R_events_entry_collision : TsukimiBehaviour
{
public void _start()
{
Debug.Log(2);
}
void Start()
{
Debug.Log(1);
}
}
How it is passedThere is no mechanism for the runtime to pass arguments into an event. The value is written into a named variable first, and the event is called afterwards
The variable’s nameThe event name with its first letter lowercased, joined to the runtime-side parameter name with its first letter uppercased (the right column of the table in the list)
If the name is off by even one characterThe write goes nowhere. The event is still called, and runs with the argument at its initial value. Neither an error nor a runtime failure appears
Who holds the mappingThe compiler holds it, checked against the event definitions the runtime holds
using UnityEngine;
using Tsukimi;
using VRC.SDKBase;
public class EventsPlayerJoined : TsukimiBehaviour
{
public override void OnPlayerJoined(VRCPlayerApi player)
{
Debug.Log(player.playerId);
}
void Start()
{
Debug.Log(1); // => 1
}
}

The runtime-side parameter name decides the variable’s name, so you are free to name your parameters as you like.

using UnityEngine;
using Tsukimi;
using VRC.SDKBase;
public class EventsParameterName : TsukimiBehaviour
{
public override void OnPlayerLeft(VRCPlayerApi who)
{
Debug.Log(who.playerId);
}
void Start()
{
Debug.Log(1); // => 1
}
}

They receive them by the same rule.

using UnityEngine;
using Tsukimi;
public class EventsTriggerEnter : TsukimiBehaviour
{
void OnTriggerEnter(Collider other)
{
Debug.Log(other.gameObject.activeSelf);
}
void Start()
{
Debug.Log(1); // => 1
}
}

There are events where the argument name in the base declaration differs from the name of the variable the runtime writes the value into There are 22. The parameter names you write are unused, so they make no difference to behaviour.

EventsArgument name in the base declarationVariable that receives the argument
InputDropvalueinputDropBoolValue
InputGrabvalueinputGrabBoolValue
InputJumpvalueinputJumpBoolValue
InputLookHorizontalvalueinputLookHorizontalFloatValue
InputLookVerticalvalueinputLookVerticalFloatValue
InputMoveHorizontalvalueinputMoveHorizontalFloatValue
InputMoveVerticalvalueinputMoveVerticalFloatValue
InputUsevalueinputUseBoolValue
OnImageLoadErrorresultonImageLoadErrorIVRCImageDownload
OnImageLoadSuccessresultonImageLoadSuccessIVRCImageDownload
OnListAvailableProductsproductsonListAvailableProductsResult
OnListProductOwnersproductonListProductOwnersResult
OnListPurchasesproductsonListPurchasesResult
OnOwnershipRequestrequestingPlayer requestedOwneronOwnershipRequestRequester onOwnershipRequestNewOwner
OnProductEventproductonProductEventResult
OnPurchaseConfirmedproductonPurchaseConfirmedResult
OnPurchaseConfirmedMultipleproductonPurchaseConfirmedMultipleResult
OnPurchaseExpiredproductonPurchaseExpiredResult
OnPurchasesLoadedproductsonPurchasesLoadedResult
OnStringLoadErrorresultonStringLoadErrorIVRCStringDownload
OnStringLoadSuccessresultonStringLoadSuccessIVRCStringDownload
OnVRCCameraSettingsChangedcameraSettingsonVRCCameraSettingsChangedCamera
using UnityEngine;
using Tsukimi;
using VRC.Udon.Common;
public class EventsInputJump : TsukimiBehaviour
{
public override void InputJump(bool value, UdonInputEventArgs args)
{
Debug.Log(value);
}
void Start()
{
Debug.Log(1); // => 1
}
}

4 events also have a declaration with no arguments. If you don’t need the argument, you can write it this way.

EventsAnother way to write it
OnDeserializationvoid OnDeserialization()
OnOwnershipTransferredvoid OnOwnershipTransferred()
OnStationEnteredvoid OnStationEntered()
OnStationExitedvoid OnStationExited()
using UnityEngine;
using Tsukimi;
public class EventsNoArgumentOverload : TsukimiBehaviour
{
public override void OnStationEntered()
{
Debug.Log(2);
}
void Start()
{
Debug.Log(1); // => 1
}
}

Ones called without writing any calling code

Section titled “Ones called without writing any calling code”

Every event in the tables above, except for the ones not in the runtime’s definitions, is called without a call written anywhere. For Interact, that’s when a player uses that object (see the example in How they’re recognized).

The text shown on approach is set by InteractionText. Setting DisableInteractive stops the object from receiving Interact, and the outline no longer appears.

using UnityEngine;
using Tsukimi;
public class EventsInteractAppearance : TsukimiBehaviour
{
public bool locked;
void Start()
{
InteractionText = "Open";
}
public override void Interact()
{
locked = !locked;
DisableInteractive = locked;
}
}

Separate from events, a method marked public is registered by name and becomes a destination for SendCustomEvent (for how to write it and the forms that error, see Getting and calling components).

Registration as a target happens even if there isn’t a single call inside that program. The caller may be in a different program, or on the runtime’s side, invisible at compile time.

OnDeserialization OnPreSerialization OnPostSerialization OnOwnershipRequest and OnOwnershipTransferred are called along with value sync and ownership. The conditions for being called are covered in Sync.

In the base classes of the distributed package, the following 6 are wrapped in conditional compilation. If the project hasn’t enabled that feature, the declaration doesn’t exist, so you can’t write it with override.

EventsCondition
OnPersistenceUsageUpdatedVRC_ENABLE_PLAYER_PERSISTENCE || VRC_ENABLE_INSTANCE_PERSISTENCE
OnPlayerDataStorageExceededVRC_ENABLE_PLAYER_PERSISTENCE
OnPlayerDataStorageWarningVRC_ENABLE_PLAYER_PERSISTENCE
OnPlayerDataUpdatedVRC_ENABLE_PLAYER_PERSISTENCE
OnPlayerObjectStorageExceededVRC_ENABLE_PLAYER_PERSISTENCE
OnPlayerObjectStorageWarningVRC_ENABLE_PLAYER_PERSISTENCE

The following 2 compile, but they aren’t in the event definitions the runtime holds. Existing code that overrides Existing code that used override still compiles as-is.

Events
OnVideoPause
OnVideoPlay

There’s 1 event that exists on the runtime’s side but not in this language. OnVariableChange is called under a different name per variable, so it can’t be placed as a single event. Overriding this Using override produces a CS0115 error.

using UnityEngine;
using Tsukimi;
public class R_events_on_variable_change : TsukimiBehaviour
{
public override void OnVariableChange()
{
Debug.Log(1);
}
}