![見出し画像](https://assets.st-note.com/production/uploads/images/173629976/rectangle_large_type_2_9de83e2fd17f5bd1758b5de9b65b1aa5.png?width=1200)
UdonSharp最適化の基礎と制限の緩和状況について
UdonSharp の概要
UdonSharp は、VRChat におけるプログラミング言語 Udon を C# 風のコードで記述できるようにする拡張ツールです。Udon は本来ノードベースのビジュアルスクリプティングであるため、テキストベースでの開発ができる UdonSharp は開発効率を大幅に向上させます。
UdonGraph との違い
標準の UdonGraph はノードをつなぐ形でスクリプトを書くのに対し、UdonSharp では C# ライクな構文でロジックを記述できる ため、可読性と保守性が向上します。しかし、最終的には Udon Assembly(Udon のバイトコード) に変換されるため、C# とは異なる制約が存在します。
基本的な書き方
コードの構造と最適な書き方
UdonSharp では UdonSharpBehaviour を継承してスクリプトを作成し、オブジェクトにアタッチして利用します。
Awake() はサポートされていないため、Start() を使用する
Update の乱用を避ける(パフォーマンスへの影響が大きい)
共通処理はクラス間の継承ではなく、ユーティリティクラスで管理
メンバ変数は可能な限り private にし、公開する場合は [SerializeField] を使用
可能な限り Unity の組み込み機能(アニメーション、シェーダーなど)を活用
シンプルなコードサンプル(基本的な UdonSharp の使い方)
using UdonSharp;
using UnityEngine;
public class LightToggle : UdonSharpBehaviour
{
public GameObject targetLight;
public override void Interact()
{
bool currentState = targetLight.activeSelf;
targetLight.SetActive(!currentState);
}
}
このスクリプトは、プレイヤーがオブジェクトを「使用」すると、targetLight のオン/オフを切り替えるものです。
よくある最適化テクニック
Update の使用を最小限にする
Update 内での計算を減らし、必要なら SendCustomEventDelayedSeconds() で代替
処理をフレームごとに分散
例えば、1000件のデータを処理する場合、100件ずつ10フレームに分ける
GetComponent<T>() の使用を減らし、キャッシュする
Start() で一度取得し、変数に保存する
ネットワーク同期の無駄を減らす
UdonSynced の変数は頻繁に更新しない
パフォーマンス最適化サンプル
using UdonSharp;
using UnityEngine;
public class SequentialActivator : UdonSharpBehaviour
{
public GameObject[] targets;
private int index = 0;
public void StartSequence()
{
index = 0;
ActivateNext();
}
public void ActivateNext()
{
if (index < targets.Length)
{
targets[index].SetActive(true);
index++;
SendCustomEventDelayedSeconds(nameof(ActivateNext), 0.5f);
}
}
}
このコードでは、ボタンを押すと 0.5 秒間隔でオブジェクトを順番に有効化する処理を実装しています。
UdonSharp の制限(2025年2月8日現在)
下記は、C# では使える機能の一部が UdonSharp では制限される例です。ただし、UdonSharp は継続的にアップデートされており、一部制限はすでに解消されつつあります。
1. ジェネリクス (List など)
以前: 非対応
現状: UdonSharp 1.2 ベータ以降で一部サポートが追加され、List<T> や Dictionary<TKey, TValue> などが“擬似実装”として利用可能になりました。ただし完全なサポートではなく、複雑なジェネリック機能は制限される場合があります。
2. クラスの継承
UdonSharpBehaviour を継承したクラス同士であれば、基本的な継承 (BaseClass -> DerivedClass) が可能
非 UdonSharpBehaviour のクラス継承は依然として不可
対処: 共通処理はユーティリティクラスや ScriptableObject 代替策などで管理
3. コルーチン (yield return)
依然として不可
StartCoroutine は使用できません
対処: SendCustomEventDelayedSeconds() やフレーム分割による擬似コルーチンで実装
4. 例外処理 (try-catch)
例外処理は 未サポート
対処: TryXXX パターン(戻り値で成功可否を返す)で代替
その他の制限
デリゲート・イベント: 未サポート
メソッドのオーバーロード: 未サポート
インターフェース実装: 未サポート
マルチスレッド: 不可
プロパティ構文 (get/set)
UdonSharp 0.20.0 以降で サポート済み
public float MyValue { get; set; } といった定義が可能
まとめ
UdonSharp はバージョンが上がるにつれ機能が拡張され、かつて不可能だった要素が段階的にサポートされつつあります。しかし、標準の C# と完全に同じ振る舞いではないため、パフォーマンス上の注意や制限機能への対処が必要です。
可能な限り Update を使わず、イベントや遅延呼び出しを活用する
ネイティブ C# ほど高速ではないので、大きな処理はフレーム分割
デリゲートやインターフェースは依然として非対応
ジェネリクスは一部サポートされ始めている
プロパティ (get/set) は対応済み
最新の UdonSharp ドキュメントやコミュニティでの情報をチェックしながら、最適な方法でワールド開発を進めてください。今後もアップデートで制限が減っていく可能性があるため、定期的にバージョン情報を追いかけるのが大切です。