【VRChat】初めてのUdonSharp:操作すると色が変わるCubeを作る

作成: 2025-12-19最終更新: 2026-09-09

U# Scriptを作り、まずログで「押せているか」を確かめてから色を変えます。C#ファイル・Program Asset・Udon Behaviourの関係と、Interactが反応しないときの切り分け順を解説します。

VRChatのワールドで、自分の書いたコードを初めて動かす。その一歩が、触ると反応するCubeです。

ただ、いきなり色まで変えようとすると、動かなかったときに困ります。押せていないのか、コードが違うのか、色の指定を間違えたのか、区別がつきません。

この記事では、まず「押せているか」をログで確かめてから、色を変える処理を足します。順番に切り分けられる形で作ります。

Cubeに触れると色が切り替わり、歯車のカードからCubeへ線がつながっている

この記事でわかること

  • C#ファイル・Program Asset・Udon Behaviourの役割
  • Interactが動いたことを、色より先にログで確かめる方法
  • 反応しないときに見る順番
  • Inspectorに出した値を、コードを触らずに変える感覚

床のあるシーンから始めます。まだなければ 最初のワールド で作れます。

Sponsored


作られるのは3つ。ノートと、翻訳カードと、名札

U# Scriptを作ると、ファイルが2つできて、Inspectorに3つ目が現れます。最初はここで混乱しがちなので、先に整理します。

C#ファイル・Program Asset・Udon Behaviourの3つの関係
  • C#ファイル(.cs は、自分が書くノートです。「押したら色を変える」はここに書きます
  • Udon Sharp Program Asset は、そのノートをVRChatが読める形に翻訳したカードです。保存すると自動で更新されるので、中を開く必要はありません。消さないでください
  • Udon Behaviour は、Cubeに付く名札です。「このCubeは、あのカードのとおりに動きます」という意味になります

直すのはノートだけです。保存すればカードが更新され、名札はそのカードを見ているだけです。

だから、同じノートを何個のCubeに貼っても、中身は共通になります。ただし「いま何色か」という状態は、Cubeごとに別々に持ちます。

Sponsored

実践:押すと色が変わるCubeを作る

完成すると、Cubeに近づいて操作するたびに、青とオレンジが交互に切り替わります。

1. Cubeとマテリアルを置く

Playを止めた状態で作業します。Play中に変えた設定は、停止すると元に戻ります。

Hierarchyで「3D Object → Cube」を作り、名前を ColorCube にします。

TransformXYZ
Position011
Rotation000
Scale111

床の上面がY=0なので、中心をY=1にすると下端が0.5になり、床に埋まらず操作しやすい高さになります。Box Colliderはそのまま、Is Triggerはオフのままにします。Rigidbodyは追加しません。 Interactに必要なのは、Colliderとプログラムだけです。

次に色を入れる器を用意します。AssetsMaterials フォルダを作り、「Create → Material」で ColorCubeMaterial を作って、Shaderを Standard にします。作ったマテリアルを ColorCube へドラッグしてください。

2. U# Scriptを作る

AssetsScripts フォルダを作り、右クリックから 「Create → U# Script」 を選びます。

ここが最初の分かれ道です。「C# Script」ではなく「U# Script」 を選んでください。C# Scriptを選ぶと普通のUnityスクリプトができてしまい、Cubeに付けてもUdonとしては動きません。隣にProgram Assetが作られないので、そこで気づけます。

名前は ColorChanger にします。ファイル名と、コードの中の class の名前は必ず一致させてください。 ずれているとコンパイルが通りません。日本語やスペースを含む名前も避けます。

3. まずログだけ出す

いきなり色を変えず、押せているかどうかだけ を確かめます。ColorChanger.cs を開いて、次の内容にして保存してください。

using UdonSharp;
using UnityEngine;

[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class ColorChanger : UdonSharpBehaviour
{
    // 「使う」操作を受け取る入口。public override を外すと呼ばれない
    public override void Interact()
    {
        Debug.Log("[ColorChanger] 押されました");
    }
}

public override void Interact() の書き方に注意してください。void Interact() だけ書いてもコンパイルは通りますが、エラーも出ないまま一生呼ばれません。これは原因に気づきにくい定番の失敗です。

Unityに戻り、コンパイルが終わるのを待ちます。次にCubeへ付けます。

  1. Hierarchyで ColorCube を選ぶ
  2. 「Add Component」で Udon Behaviour を追加する
  3. Program Source へ、Projectの ColorChanger の Program Asset をドラッグする

ここで一度Playします。Gameビューをクリックして操作を移し、Cubeに照準を合わせてください。操作案内が出たら、デスクトップでは左クリックです。

Consoleに「押されました」が出れば成功です。 ここが通ってから、色の処理を足します。

4. 色を変える処理を足す

Playを止めて、コードを次の内容に置き換えます。

using UdonSharp;
using UnityEngine;

[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class ColorChanger : UdonSharpBehaviour
{
    [SerializeField] private MeshRenderer targetRenderer;  // 色を変える相手
    [SerializeField] private Color startColor = Color.blue;
    [SerializeField] private Color changedColor = new Color(1f, 0.5f, 0f);

    private Material instanceMaterial;  // このCube専用のマテリアル
    private bool isChanged;             // いま切り替わっているか

    private void Start()
    {
        if (targetRenderer == null)
        {
            Debug.LogWarning("[ColorChanger] Target Rendererが未設定です。");
            return;
        }

        instanceMaterial = targetRenderer.material;
        instanceMaterial.color = startColor;
    }

    public override void Interact()
    {
        if (instanceMaterial == null) return;

        isChanged = !isChanged;                                        // 真偽を反転する
        instanceMaterial.color = isChanged ? changedColor : startColor; // 条件で選ぶ
    }
}

コードは3つに分かれています。

設定する値 が最初の3行です。[SerializeField] が付いているので、private でもInspectorから設定できます。

最初の準備Start() です。相手が未設定なら理由をConsoleに出して止まります。設定されていればマテリアルを取り出し、最初の色にします。

押されたときの処理Interact() です。isChangedtruefalse を持つ変数で、! を付けると反転します。条件 ? A : B は、条件が真ならA、偽ならBを選ぶ書き方です。

操作isChanged表示される色
起動直後false
1回目trueオレンジ
2回目false

毎フレーム動く Update() は使っていません。押された瞬間だけ処理が走ります。

targetRenderer.material を使っているのには理由があります。これは そのRenderer専用のマテリアル を取り出します。もし sharedMaterial を書き換えると、同じマテリアルを使っている他のCubeまで一緒に色が変わってしまいます。

5. 参照を割り当てる

Unityに戻ると、Udon Behaviourに設定欄が増えています。

C#からProgram Asset、Udon Behaviourへつなぎ、Target RendererにCubeのMesh Rendererを指定する
  1. Target Renderer へ、Hierarchyの ColorCube をドラッグする(同じオブジェクトのMesh Rendererが入ります)
  2. Start Colorが青、Changed Colorがオレンジになっていることを確認する
  3. Interaction Text色を変える にする
  4. シーンを保存する

Interaction Textは、近づいたときに表示される案内です。空でも押せます。押しやすくするための表示なので、何が起きるかが分かる短い言葉にします。

6. ClientSimで確かめる

Playして、Gameビューをクリックしてから、Cubeに近づきます。

操作期待する結果
Cubeに照準を合わせる「色を変える」の案内が出る
操作する(左クリック)青からオレンジへ変わる
もう一度操作する青へ戻る
Playを止めてもう一度始める青から始まる
操作するたびにCubeの色が変わる

以前の作例を撮影したものです。この記事のコードでは、青とオレンジの2色で切り替わります。

SceneビューでCubeをクリックするのと、Gameビューでプレイヤーとして操作するのは別です。 クリックして枠が光るだけなら、編集画面のほうを触っています。

反応しないときの見る順番

上から順に確かめると、どこで止まっているかが分かります。

上から順に確かめる4つ
  1. 照準を合わせて、案内が出るか → 出ないなら、Colliderがあるか、遠すぎないか、手前に別のオブジェクトがないか
  2. Consoleに押したログが出るか → 出ないなら、public override void Interact() の書き方か、Program Sourceが空か
  3. Consoleに赤いエラーが出ていないか → 出ているなら、いちばん上のエラーのファイル名と行番号を見る
  4. Target Rendererが None になっていないか → 起動時に警告が出ているはずです
  5. 色が変わらないなら、2色が同じ値になっていないか

よくある失敗をもう2つ挙げます。空の親オブジェクトにプログラムを付けて、Colliderは子のCubeにある 場合、Interactは動きません。同じオブジェクトに両方が必要です。もう1つは、Play中にInspectorを編集して、停止したら消えた というものです。設定はPlayを止めてから入れて保存します。

Sponsored

値を変えて確かめる

動いたら、2つ試してみてください。コードを触らずに結果が変わることが実感できます。

Changed Colorだけ緑に変える。 コードは1文字も変えていないのに、2回目の色が変わります。Inspectorの値がそのまま処理に渡っていることが分かります。

Cubeをもう1つ置いて、Target Rendererに2個目を指定する。 1個目を押すと、2個目の色が変わります。操作を受け取る場所と、結果が出る場所は別にできる という、これから何度も使う考え方です。

ここまでで、イベント・状態・参照の3つを使いました。

おまけ:先に知っておくと良いこと

  • Debug.Logは最初の相棒: 動かないときに「ここまで来ているか」を確かめられます。処理の入口に1行入れるだけで、原因が半分に絞れます
  • Interactは近づかないと押せない: 既定の距離はおよそ2mです。遠くに置いたオブジェクトが反応しないときは、まず近づいてみてください
  • VRC Pickupと一緒に付けない: 掴む操作が優先されて、Interactが動かなくなります
  • 同期はまだ考えない: このコードは押した人の画面でしか色が変わりません。全員に伝えるのは ネットワーク同期入門 の話です
  • Play中の変更は保存されない: 色や位置をPlay中に調整したら、値をメモして、停止してから入れ直します

まとめ

最初のUdonSharpは、3つのつながりでできています。

  • ノート(C#ファイル)を書くと、翻訳カード(Program Asset)が自動でできる
  • そのカードを、Cubeの名札(Udon Behaviour)に差す
  • 色より先に、ログで「押せているか」を確かめる
  • public override void Interact() の書き方を外すと、エラーなしで無反応になる

うまくいかないときの問いかけは、「案内は出るか、ログは出るか」 です。この2つで、原因が入力側かコード側かに分かれます。

プログラミングが初めてなら、次は プログラムの4つの部品 で変数・if・for・関数を通しでつかんでください。書き方が分かっているなら 変数と参照メソッドとカスタムイベント へ進みます。

VRChat このセクションのノート63