Random Tips & Performance pointers - MerlinVR/UdonSharp GitHub Wiki

Random Tips & Performance pointers

This page contains a list of things to keep in mind while using Udon with U#.

Udon is slow

Do not expect to do a massive complex algorithm that iterates over thousands of elements. Udon can take on the order of 200x to 1000x longer to run a piece of code than the equivalent in normal C# depending on what you're doing. What this means is that if you're doing anything that iterates on Update, you probably shouldn't. Want to iterate over 40 GameObject's and rotate them? Do it in an animation instead. Just 40 iterations of something can often be enough to visibly impact frame rate on a decent computer. If there's any built-in Unity or VRC component that you could use to do a task you're considering using Udon for, use the component instead. If you must use Udon to do a lot of things at once, time slice your code where it's possible. And you will need to make compromises where it's just not viable to do something.

Network event scoping

In order to send a CustomNetworkEvent, the target method must be public. If it is not public, it will not fire. Additionally, as of VRChat 2020.4.4 any methods that start with an underscore such as _MyLocalMethod will not receive network events. Generally for code readability, you should probably just keep any methods you don't want to get called from SendCustomNetworkEvent as private. Put an underscore in front of the method name if you want a public method that's callable locally by other UdonSharpBehaviours, but not callable over the network.

SendCustomEvent & method calls across behaviours

In order to call SendCustomEvent on a method on an UdonBehaviour, the method must be marked public similar to the network events. Additionally, calls across behaviours will be somewhat slower than local method calls due to how Udon handles SendCustomEvent which is used internally for those cases. When you can, prefer to keep similar behavior in one UdonSharpBehaviour rather than separating it into different behaviours.

Prefer to keep methods as private if they are not being called from other scripts. Due to how Udon searches for methods to call, the fewer public methods you have, the better performance-wise.

Don't use collision ownership transfer on UdonBehaviours

Collision ownership transfer has been bugged for a long time, and will intermittently cause ownership transfer spam that lags out everyone in the world.

Avoid using GetComponent<T> frequently

This is a general Unity best practice because GetComponent<T>() is slow, but it's especially true in Udon's case when you're using GetComponent to get an UdonSharpBehaviour type. This is because UdonSharp needs to insert a loop that checks all UdonBehaviours to make sure they're the correct UdonSharpBehaviour type. When you can, only use GetComponent on Start or on some event that happens infrequently.

U# script files must be connected to one and only one (1) UdonSharpProgramAsset

UdonSharpProgramAssets are the Udon analogue to 1 script, do not change the script assigned to an UdonSharpProgramAsset after it is in use in a scene or you may experience weird issues.