Skip to content

Exporting to UdonSharp

This exports a Behaviour written in TsukimiSharp as C# that UdonSharp reads. Use it when you hand the code to an UdonSharp project, or when you submit to a place that specifies which compiler to use.

  1. In the Project view, select the .cs of the Behaviour you want to export
  2. Choose Export as UdonSharp from the right-click menu
  3. Decide where to save it
What to selectThe .cs of the Behaviour. If you select the paired program asset instead, the menu stays grayed out
What gets exportedOnly the one you selected
Resolving type namesThis uses the same range as compiling that program does. A Behaviour that refers to a type placed in another file can be exported as it is
Where you can save itOutside the Unity project. The save window opens on the folder one level outside the project
If you pick somewhere inside the projectThe export stops and the reason is shown
Why it cannot go insideThe exported .cs is compiled by that project too, and it declares a class with the same name as the original script. The project then holds two classes of that name, and neither of them compiles
How the class name is decidedIt comes from the file name of the original .cs, not from the name you save it under. Changing the name you save it under leaves the class name as it was
CompilerThe exported .cs is compiled by UdonSharp. The optimization the TsukimiSharp compiler performs does not apply to the code after it is exported
The order of synced variablesA program built from the exported code can end up with a different order of synced variables. If the order differs, it cannot connect to instances that are still running the original program
CommentsThe comments you wrote on declarations, and the namespace declaration, remain in the exported code
Temporary variablesTemporary variables the compiler created are declared together at the top of each method. The line count grows compared with the original code
Method namesMethods that cannot be told apart by name alone, such as those implementing an interface, get a name that includes the argument types
Attributes[NetworkCallable] (with its per-second limit) is written in the exported code too. A method that comes back to itself through direct calls, and a method that may be entered again through another Behaviour, get [RecursiveMethod] (Entering a method again while it runs)
CaseWhat is shown
The original code does not compileYou are told to fix the errors in the console and try again
The code contains something that cannot be expressed as UdonSharpYou are told which way of writing is the reason
A method may be entered again while it runs, through one of this Behaviour’s own events that starts on the spotThis compiler keeps the method’s local variables across that call, and UdonSharp does not, so the exported script would run differently. The reason is shown (Entering a method again while it runs)
A [NetworkCallable] method is not registered as an entry point under its own nameUdonSharp could not call it over the network by that name, so the reason is shown

In every case, no file is created.

How it comes backExport
It calls itself directlyIt is exported with [RecursiveMethod]
It comes back from one of this Behaviour’s own events that starts on the spot (below)The export stops
It may come back through another Behaviour (a method call on a field or variable of another class, SendCustomEvent with an event name this Behaviour does not have, SetActive on another GameObject, and the events of other Behaviours that Networking.SetOwner or SetParent starts)That method, and each method that can still be running when the call comes back, is exported with [RecursiveMethod]. UdonSharp then keeps the local variables across the call as well
The window shown after the exportWhen a method gets [RecursiveMethod] because it may come back through another Behaviour, the heading becomes Three things to know. and the third point names those methods. A method marked for direct recursion is not listed
CostUdonSharp saves and restores the local variables of a method marked [RecursiveMethod], so the exported program is larger than it would be without the mark
How this compiler saves themOn the Attributes page

Calls that start this Behaviour’s own events on the spot

Section titled “Calls that start this Behaviour’s own events on the spot”
CallsEvent it starts
SendCustomEvent or SendCustomNetworkEvent (to any target but Others) sent to this Behaviour or to a value holding a Behaviour, naming one of this Behaviour’s events or taking the name from a variableThe event of that name. When the name is in a variable, any event is taken as able to start. A value holding a Behaviour counts because it may be this one
SetProgramVariable on a field of this Behaviour that receives value changesThe change notification of that field
A method call on a field or variable whose type is this class, its base class or an interface it implementsThat method. The field or variable may refer to this Behaviour
SetActive on its own GameObjectOnEnable・OnDisable
Networking.SetOwnerOnOwnershipTransferred
A VRCPickup’s Drop, a VRCStation’s UseStation and ExitStation, and RespawnThe event of this Behaviour that each of them starts
A VRCObjectPool’s TryToSpawn and ReturnOnEnable・OnDisable
A call that changes the parent or sibling order of any Transform (SetParent, assigning parent, DetachChildren, SetSiblingIndex and the like)OnTransformParentChanged and OnTransformChildrenChanged. That Transform may be this Behaviour’s own, its parent’s or a child’s
Setting a UI value such as a slider’s valueAny of its events