Overview
UdonSharp uses C# syntax for programming, but since the code runs in a special environment called the Udon VM, not all standard C# features are available. To develop efficiently, it's essential to accurately understand what is and isn't available.
This article specifically explains the major C# features available in UdonSharp development and the main limitations imposed by Udon VM constraints.
Available C# Features
UdonSharp supports many basic C# features. By combining these, you can implement most gimmicks.
1. Variables and Data Types
- Basic Data Types: All basic value types like
int,float,double,bool,string,charare available. - Unity Types: Most classes and structs provided by the Unity engine, such as
Vector3,Quaternion,Color,GameObject, can be used. - Arrays: One-dimensional arrays like
int[],GameObject[]can be used without issues. Multi-dimensional arrays (e.g.,int[,]) are also supported.
public class VariableExample : UdonSharpBehaviour
{
// Basic data types
public int score = 0;
public string playerName = "Default Player";
public bool isGameActive = false;
// Unity types
public Vector3 initialPosition = new Vector3(0, 1, 0);
public GameObject targetObject;
// Arrays
public Transform[] waypoints;
}
2. Control Structures
Control structures for managing program flow can be used just like in standard C#.
- Conditionals:
if,else if,else,switch - Loops:
for,foreach,while,do-while - Jumps:
break,continue,return
void CheckScore()
{
if (score >= 100)
{
Debug.Log("Victory!");
}
else
{
Debug.Log("Not enough yet");
}
}
void ProcessWaypoints()
{
foreach (Transform waypoint in waypoints)
{
Debug.Log(waypoint.name);
}
}
3. Methods (Functions)
Methods for grouping processing can also be defined and called. Parameters and return values are supported.
// Method with return value and parameters
private int Add(int a, int b)
{
return a + b;
}
void CalculateSum()
{
int result = Add(5, 3); // result becomes 8
Debug.Log(result);
}
4. Properties
C# properties (getters and setters) are also supported.
private int _health = 100;
public int Health
{
get { return _health; }
set { _health = Mathf.Clamp(value, 0, 100); }
}
5. Other Supported Features
The following features are also available in UdonSharp.
- out/ref Parameters: The
outandrefkeywords can be used in method parameters. - Extension Methods: You can add custom methods to existing types.
- Null-conditional Operators: The
?.and??operators can be used. - String Interpolation: You can write things like
$"Score: {score}".
// out parameter example
public bool TryGetPlayerScore(string playerName, out int score)
{
// Processing...
score = 100;
return true;
}
// Calling side
if (TryGetPlayerScore("Player1", out int result))
{
Debug.Log($"Score: {result}");
}
6. Classes and Inheritance
The basic approach is to create classes that inherit from UdonSharpBehaviour.
Important Limitation: In UdonSharp, instantiating custom classes with the
newkeyword is not supported. If you want to manage data, define multiple variables directly or use arrays.
// Correct data management approach in UdonSharp
public class GameManager : UdonSharpBehaviour
{
// Define multiple variables directly
private int playerHealth;
private int playerMana;
private string playerName;
// Use arrays to manage data for multiple players
private int[] playerScores;
void Start()
{
playerHealth = 100;
playerMana = 50;
playerName = "Player";
playerScores = new int[10]; // Array initialization is possible
}
}
Main Limitations and Workarounds
Due to the Udon VM's design philosophy (security and cross-platform compatibility), several C# features are intentionally restricted.
1. Generics
- Limitation: Generic collections like
List<T>,Dictionary<T, K>,Queue<T>cannot be used. - Reason: The Udon VM doesn't support generics that dynamically generate types at runtime.
- Workarounds:
- Arrays (
T[]): The most basic alternative. Use when the number of elements is fixed or the maximum is predictable. - VRChat SDK's DataToken: Use Udon-compatible data containers like
DataListandDataDictionary. These are also designed with network synchronization in mind. (Details will be covered in advanced topics.)
- Arrays (
2. File I/O (System.IO)
- Limitation: Classes in the
System.IOnamespace (File,StreamReader, etc.) cannot be used. Reading or writing to local files is not possible at all. - Reason: For security. Prevents worlds from having malicious programs read or write files on users' PCs.
- Workarounds: If you want to save data in a world, consider using
VRCPlayerApipersistence features provided by theVRChat SDK(advanced topic).
3. Network Communication (System.Net)
- Limitation: Features for communicating with arbitrary web servers, such as
HttpClientorWebRequest, cannot be used. - Reason: For security. Prevents redirecting to phishing sites or sending information to external servers.
- Workarounds: Only specific features permitted by VRChat, such as
VRCStringDownloaderprovided by theVRChat SDK, are available.
4. Pointers and Unsafe Code
- Limitation: The
unsafekeyword and pointer operations cannot be used. - Reason: Pointers that directly manipulate memory carry high risks of destabilizing programs or creating security vulnerabilities.
5. Interfaces
- Limitation: C# interfaces (
interface) cannot be used. - Reason: The Udon VM doesn't support the interface concept.
- Workarounds: If you want to define common processing across multiple scripts, consider inheritance from a base class or loosely coupled design using
SendCustomEvent.
6. Method Overloading
- Limitation: Methods with the same name but different parameter types or counts (overloading) cannot be used.
- Reason: The Udon VM doesn't support distinguishing methods with the same name.
- Workarounds: Define methods with different names. For example, distinguish purposes by name like
Move(Vector3 target)andMoveToPlayer(VRCPlayerApi player).
// ❌ Example that doesn't work (overloading)
// public void Move(Vector3 target) { }
// public void Move(Transform target) { }
// ✅ Correct alternative
public void MoveToPosition(Vector3 target) { }
public void MoveToTransform(Transform target) { }
7. Exception Handling (try/catch)
- Limitation: Exception handling with
try-catch-finallysyntax cannot be used. - Workarounds: Use defensive coding by checking conditions before processing that might cause errors.
// ❌ Cannot be used
// try { DoSomething(); } catch { }
// ✅ Alternative: Pre-check
if (targetObject != null)
{
DoSomething();
}
Limitations Summary Table
| Feature Category | Limitation | Workaround |
|---|---|---|
| Generics | List<T>, Dictionary<T, K>, etc. | Arrays (T[]), DataList |
| Interfaces | Defining/implementing interface | Inheritance or SendCustomEvent |
| Method Overloading | Same-named methods with different parameters | Define methods with different names |
| Exception Handling | try-catch-finally syntax | Pre-condition checking (defensive coding) |
| File I/O | File read/write using System.IO | None (security constraint) |
| Networking | Arbitrary communication using System.Net | SDK-provided features like VRCStringDownloader |
| Pointers | unsafe code, pointer operations | None (security constraint) |
| Threading | Multithreading using System.Threading | None (Udon runs single-threaded) |
Support Status Quick Reference
| Feature | Support Status |
|---|---|
Basic data types (int, float, bool, string) | ✅ Supported |
Arrays (T[]) | ✅ Supported |
Control structures (if, for, switch, etc.) | ✅ Supported |
| Method definitions | ✅ Supported |
| Properties (getter/setter) | ✅ Supported |
out/ref parameters | ✅ Supported |
| Extension methods | ✅ Supported |
Null-conditional operators (?., ??) | ✅ Supported |
Generics (List<T>, etc.) | ❌ Not Supported |
| Interfaces | ❌ Not Supported |
| Method overloading | ❌ Not Supported |
Exception handling (try-catch) | ❌ Not Supported |
async/await | ❌ Not Supported |
Approach When Facing Limitations
When developing with UdonSharp, you may be confused when features you take for granted in regular C# development aren't available. In such cases, keep the following points in mind:
- Read Error Messages: When you try to use an unsupported feature, the UdonSharp compiler usually outputs a clear error message like "
[UdonSharp] The C# feature 'X' is not supported". Check the console first. - Look for Alternatives: Consider the purpose—why you wanted to use that feature—and explore whether you can achieve the same thing with arrays or other UdonSharp features.
- Refer to Official Documentation: VRChat and UdonSharp official documentation sometimes describes recommended approaches for achieving specific goals.
Summary
- In UdonSharp, many basic C# features like variables, control structures, and methods are available.
- On the other hand, some features cannot be used due to Udon VM constraints, such as generics, file I/O, and free network communication.
- These limitations are primarily established to ensure security and cross-platform compatibility.
- When facing limitations, it's important to check error messages and consider ways to achieve your goals using alternatives like arrays.
Understanding the boundary between available and unavailable features is the first step to efficiently mastering UdonSharp.