Udon Best Practices

Let’s post about some best practices you’ve found for the sake of ease and performance. Feel free to contribute! If relevant, post your Udon paste string too.

Be Careful what you do OnUpdate!

Update runs every single frame, so if you put expensive things in there, it gets bad, fast. Be careful.

In particular, GetComponent is pretty slow. If you can do it once in Start instead, then you probably should do so. Custom Events can also be useful for this, if you’re spawning in a new prop or something.

If you want to only execute something every so often, consider keeping track of elapsed time since last execution using deltaTime or something similar and only executing every N seconds by comparing (and then resetting) your internal timer value.

Be Careful with Instantiate!

You can cause some serious problems if you’re instantiating something that also instantiates on Start. Exponentials are scary!

Referencing Self

Remember: Transform, GameObject, and UdonBehavior slots default to the object that your Udon Program is running on. If that’s what you’re trying to target, you don’t need to plug in anything at all!

Check the console!

The console is your best friend when something goes awry. Udon VM exceptions and errors will pop up when they occur, and typically have a stack dump and detailed stacktrace included. Dig a little bit, and you’ll probably be able to figure it out.

If not, feel free to post your issue (with Udon Assembly, screenshots, Udon paste strings, etc) in the Questions category.

Ghosts in the Machine

Sometimes things get a bit wonk, in a weird state, or just doesn’t work right. Try saving and reloading your graph/scene/project first! If you can reliably reproduce an issue, remember to file a bug report so we can fix it!

Check out my Profile

Use the Unity profiler to see how your Udon is running! Search for UdonBehavior in the profiler to see only Udon’s timings. The “Time ms” column is a good way to see how long your script is running per-frame. Keep in mind that to get 90FPS, you need about 11ms or so-- and everything else running (avatar rendering, world rendering, systems, etc) are already eating up a lot of that 11ms!

Try to keep your graphs below a half ms or so, if you can.

Share your noodles

You can easily copy and paste nodes to each other! VRChat Udon encodes copy and paste into a compressed, encoded string that is easily pastable to others. Copy it to your clipboard and paste it into the graph, and it’ll work!

If you’re familiar with Factorio, it works a lot like their blueprint strings.

Only Update when you need to!

Putting everything on Update is a quick way to murder every frame you’ve got. If you are getting data from the scene, you should only be getting that data when you need it.

Ask yourself “How often does this data need to be updated? Does it update only during certain events?” In essentially all cases, it’s cheaper to get a variable than to recalculate its value, especially for complex types. Restrict updating your “large” data type variables (like arrays of players) only when you need to, like when a new player joins or one leaves.

You can also “throttle” your update rate by using Delta Time and tracking how long its been since you’ve run your last update:

Udon Paste Code
AO1YW0/cRhT+K2ied9DcPBckHpqERlGrpiqXlwit5nKGuDU29dppEeGX5aE/qX8hZ5cFAjbUVUHQtPKu5PF6zp7r950zf37644x88FUPZOvdGcl9Vf3gj3FBdj5A3c33T5LvgMxIXyZ86L2VxtpAoYBAVciaWskTBRMTM1HYbCO+fNIsyq5sarJ1Rn4nW1Rotclm5BRvnd5k5zNSNwn237xa4L8ezkiumt/WK5KtkJEbT7XgmSrNGe4RBXU8+pQYCy4BObyQcLBUfCXjfHZD+QPflj5UMN89XXRwvFvWR9W1FdIGGTNKD0FItIJ7aosEVDjpHU9Rx+RGrJD60ghh7W0rCG64/ty06ba2Z6Svy+70bfgZYndw4fwzUtaLztcR3rwiW0vhi65Ftdc/E7K08O9vu7B/c3f1cLZxvIhNW5VhtnEA7QJt28bALK/Zxsu+6voWtmvou9ZXs40f+1CV8Ts43Wt+gXo7GOOLWGjupAJm3ceuPAZ0bITv/aJb58k/UvJF01Tg64fV8ltfLb42vcj57Xx/0eLb768SXLnsfcQy1SYlqqQ1NPhsqDXCZyEKlZweJrh0+u4qJUrooKJjNGQHVDmWqJNWUgcsGAaZyew/MnK7mrFknVOaCsCSVg4kDS4zmqXzeGmVZTGo5ofxyf5Sxk59VNawh6m6OZ8fQTdPUHV+uZ6PYwPiizY8O8q5NFRxBtSnnGl23ASdhLZCjWGDvUQ4LsX9CPdX2LWLWl7i15Vak1BxqBZn9p6Q4gbJQSoRNDVJcaq8DtQDl1TbqIR1BTDvhlGdlF8PEdVHhK9JJPBQ9Xk/HxWc85iZoEFqzLkkJfXRBBoLo7TljCljh8Hl2j4hH11GZmXJw0ameH5c16/o7Sf87kJs6rR4hoyy1/ZfP9F9WT+I6M3J/JuUVlVxE89vLu5oAydg3ximOrGuuxFINSGGZKKnAQEEZRacWhYEjZATMGS7bBji6WwSzwyA9wkbyWEoXo/x1BT7R3yqrrBMjtDU46HXk/HKJGf6wovMA/ZNPGlsnpBhkXgtLbBzCr5gpjBy6MzrTkSPsMJ/1ZdBgmMgsVvhFhuoQmgaCmygtOQMcYCzyNJ9HCsU+5c7c1KXMQFwX7eAPNjuvff123bn195XE6B3TS3XE8qEaWJkQmFsHQ41TO0p1bKC3imp8Lyhd3xEmDJqDdHi+mhmNSyMjAgpFgrMsgg9yl2e/lhkR2owsXjEcUf7kcEv2FhwgEgDAO4KQWHeeUaFFIWMKUgV5f8jwhcxfdnghjsalQkRGEZW88s+hQ8m0sc5oTrE6zM=

This graph will only execute the True branch when 5 seconds (defined by updateRateSeconds) have passed since the last time it ran.

2 Likes

I was hoping of doing this my self, but instead use a manager script that does the update checks & the delay and then send a Custom Event call to all the needed scripts (to avoid duplicating code), but when i try use a VRCUdonBehaviourArray the Assemly returns Error “Type referenced by ‘VRCUdonBehaviourArray’ could not be resolved”.

UdonBehaviour Array isn’t supported just yet. It’s being added soon.