UdonSharp Documentation

repository·master·Indexed 19 days ago

https://github.com/vrchat-community/udonsharp

A compiler that translates C# code into Udon assembly, allowing developers to create interactive VRChat worlds using standard C# syntax. Includes guides on installation via VRChat Creator Companion, script creation, project configuration, and using the Class Exposure Tree to verify Udon compatibility.

Tokens
22.9K
Snippets
48
Records
100
Agent score
68%

What's inside UdonSharp

  1. Understand Synced Variables and Data Sizes

    master

    Variables marked with the [UdonSynced] attribute are synchronized across the network.

    Important Considerations:

    • Serialization Overhead: The 'size' listed below refers to approximate memory size. When networked, data is serialized, which may increase the actual transmitted byte count. For example, a bool typically sends at least 1 byte.
    • Monitoring Traffic: To determine the exact amount of serialized data being sent, use the byteCount property within the OnPostSerialization event.
    • Network Specs: For detailed information on networking, refer to the official Udon Network Specs.
    ### Boolean types
    | Type | Size |
    | ---- | ---- |
    | bool | 1 byte |
    
    ### Integral numeric types
    | Type | Range | Size |
    |--------|---------------------------------|---------|
    | sbyte | -128 to 127 | 1 byte |
    | byte | 0 to 255 | 1 byte |
    | short | -32,768 to 32,767 | 2 bytes |
    | ushort | 0 to 65,535 | 2 bytes |
    | int | -2,147,483,648 to 2,147,483,647 | 4 bytes |
    | uint | 0 to 4,294,967,295 | 4 bytes |
    | long | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | 8 bytes |
    | ulong | 0 to 18,446,744,073,709,551,615 | 8 bytes |
    
    ### Floating-point numeric types
    | Type | Approximate range | Precision | Size |
    |--------|-------------------------------|-------------|--------|
    | float | ±1.5 x 10^(−45) to ±3.4 x 10^(38) | ~6-9 digits | 4 bytes |
    | double | ±5.0 × 10^(−324) to ±1.7 × 10^(308) | ~15-17 digits | 8 bytes |
    
    ### Vector mathematics types and structures (Unity)
    | Type | Range | Size |
    |--------|-------------------------------|-------------|
    | [Vector2](https://docs.unity3d.com/ScriptReference/Vector2.html) | same as float | 8 bytes |
    | [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | same as float | 12 bytes |
    | [Vector4](https://docs.unity3d.com/ScriptReference/Vector4.html) | same as float | 16 bytes |
    | [Quaternion](https://docs.unity3d.com/ScriptReference/Quaternion.html) | same as float | 16 bytes |
    
    ### Color structures
    | Type | Range / Precision | Size |
    |--------|-------------------|--------|
    | [Color](https://docs.unity3d.com/ScriptReference/Color.html) | same as float | 16 bytes |
    | [Color32](https://docs.unity3d.com/ScriptReference/Color32.html) | same as byte | 4 bytes |
    
    ### Text types and structures
    | Type | Range | Size |
    |--------|----------------|--------|
    | char | U+0000 to U+FFFF | 2 bytes |
    | string | same as char | 2 bytes / char |
    
    ### Other structures
    | Type | Range | Size |
    |--------|----------------|--------|
    | [VRCUrl](#vrcurl) | U+0000 to U+FFFF | 2 bytes / char |
  2. Optimize network event scoping for CustomNetworkEvent

    master

    When using SendCustomNetworkEvent, the target method must be public to be reachable. To prevent methods from being triggered over the network while still allowing them to be called locally by other UdonSharpBehaviours, prefix the method name with an underscore (e.g., _MyLocalMethod).

    For maximum security and clarity, keep methods private if they do not need to be called by other scripts. This prevents accidental network calls and improves performance.

  3. Understand UdonSharp Proxies for Editor Scripting

    master

    UdonSharp uses a 'proxy' system for editor scripting. When you create an U# script, UdonSharp creates a C# version of your behaviour (the proxy) and links it to the actual UdonBehaviour.

    Key Proxy Characteristics:

    • Interaction: Editor scripts should interact with the proxy (the C# version) rather than the UdonBehaviour directly.
    • State: Proxies act similarly to Unity's SerializedObject; changes to the proxy must be synchronized with the original object.
    • Lifecycle: Proxies are created on the same GameObject as the UdonBehaviour, are marked as hidden, and are always disabled.
    • Warning: Never re-enable proxy behaviours, as this can cause logic to run twice during gameplay. Because they are disabled, methods like GetComponentInChildren will not find them unless configured to include disabled components.
    • Builds: Proxies are editor-only and are not saved in scenes or builds.
  4. Optimize SendCustomEvent and cross-behaviour calls

    master

    To call a method via SendCustomEvent on an UdonBehaviour, the target method must be public.

    Performance Tips:

    • Minimize Public Methods: Udon performs a search to find methods to call. Reducing the number of public methods improves performance.
    • Reduce Cross-Behaviour Calls: Calling SendCustomEvent across different behaviours is slower than local method calls. Where possible, consolidate related logic into a single UdonSharpBehaviour instead of splitting it across multiple components.
  5. Important differences between UdonSharp and standard Unity C#

    master

    UdonSharp is a compiler for Udon assembly and does not follow the full C# language specification. Note the following behavioral differences:

    • Inheritance: Always inherit from UdonSharpBehaviour instead of MonoBehaviour for the best experience.
    • Component Access: Generic GetComponent<T>() works for standard Unity components, but for UdonBehaviour, you must use the non-generic version: (UdonBehaviour)GetComponent(typeof(UdonBehaviour)).
    • Collections: Only standard arrays [] are supported. List<T> is not currently supported.
    • Initialization: Field initializers are evaluated at compile time. If your initialization logic depends on other objects in the scene, perform that logic in the Start() method instead.
    • Networking: Use the [UdonSynced] attribute on fields that need to be synchronized across the network.
    • Type Checking: Numeric casts are checked for overflow due to UdonVM limitations.
    • Type Abstraction: .GetType() may return unexpected types because U# abstracts certain types for Udon compatibility. For example, a jagged array (e.g., int[][]) will return object[] instead of the specific jagged type.
    • Struct Mutation Bug: Mutating methods on structs (like calling .Normalize() on a Vector3) will not modify the original struct due to an underlying Udon bug.
  6. Use UdonSharpBehaviour instead of UdonBehaviour in C#

    master

    In UdonSharp code (the U# script itself), UdonBehaviour and UdonSharpBehaviour are treated as the same object. However, in C# Editor scripts, they are different. UdonSharpBehaviour does not inherit from UdonBehaviour.

    Best Practices:

    • Variable Types: Always prefer using UdonSharpBehaviour as a variable type instead of UdonBehaviour to ensure the proxy system handles references correctly.
    • Reference Handling: The proxy system automatically converts references to other UdonSharpBehaviour proxies. If you use UdonBehaviour or generic Component types, the system will only populate the reference to the underlying UdonBehaviour, which may cause references to be cleared to null on build if they are not specifically UdonSharpBehaviour types.
  7. Deploy the website

    master

    You can deploy the website using different methods depending on your hosting setup.

    Using SSH

    To deploy via SSH, set the USE_SSH environment variable to true:

    $ USE_SSH=true yarn deploy

    Using GitHub Pages

    To deploy to GitHub Pages, provide your GitHub username via the GIT_USER environment variable. This command builds the site and pushes it to the gh-pages branch.

    # Using SSH
    $ USE_SSH=true yarn deploy
    
    # Using GitHub Pages
    $ GIT_USER=<Your GitHub username> yarn deploy