【VRChat】動かないときの直し方:入口に1行のログを置く

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

押しても動かないボタンを、ConsoleとDebug.Logで原因まで追い詰めます。入口のログで切り分ける順番と、ClientSim・Build & Test・実機の使い分けを解説します。

ボタンを作りました。押しても、何も起きません。

コードを何度も読み返して、それらしいところを直しては試す。1時間たっても直りません。実際の原因は、コードではなく ボタンにColliderが付いていなかったこと でした。

押した操作がそもそも届いていないのか、届いたあとで止まっているのか。 ここを先に決めれば、探す範囲は半分になります。この記事では、その決め方を扱います。

入口に置いた1行のログが、探す範囲を半分にする

この記事でわかること

  • 入口のログで切り分ける順番
  • Consoleの見方と、見落としやすいところ
  • ClientSim・Build & Test・実機の使い分け
  • ログが出ないときの原因

メソッドとカスタムイベント を試した状態から始めます。

Sponsored


中を読む前に、入口を見る

動かないコードを前にすると、中身を読み返したくなります。その前にやることがあります。

メソッドの先頭に、ログを1行だけ置いてください。

public override void Interact()
{
    Debug.Log("[DoorButton] 押された");   // 入口のログ
    // ...
}

Playして押してみます。このログが出るか出ないかで、世界が2つに分かれます。

入口のログが出るかどうかで、探す場所が分かれる
結果意味見るところ
出ない押した操作が届いていないCollider、Udon Behaviourの割り当て、オブジェクトが有効か
出る押した操作は届いている参照の割り当て、if の条件、同期

出ないときは、コードの中を1行も読まないでください。 そこは呼ばれていないので、いくら読んでも原因はありません。

この切り分けが、デバッグでいちばん大きな一歩です。あとは同じことを、少し先で繰り返していきます。

Consoleウィンドウ(Window → General → Console)で気をつけるのは2点です。

  • Playする前に赤いエラーが出ていないか。 コンパイルが通っていないと、直す前のスクリプトが動いています
  • Collapseがオンだと、同じログがまとまります。 何回押されたかを見たいときはオフにします
Sponsored

3つの実験場を使い分ける

確かめる場所は3つあります。上級・初級の順ではなく、何を確かめたいか で選びます。

ClientSim・Build & Test・実機で確かめられることが違う
場所確かめられること確かめられないこと
ClientSim(UnityのPlay)入口まで来たか、参照漏れ、if の分岐、表示の切り替え同期、VRの手、端末の性能
Build & Test(複数クライアント)同期、所有権、途中参加、実際の操作感端末ごとの性能、通信の遅さ
アップロードして入る実際の見え方、読み込み時間、他の人のアバターとの兼ね合いログをその場で読むこと

ConsoleとDebug.Logが同じ画面で完結するのは、ClientSimだけです。 だからまずここで直します。

同期が絡む問題に見えても、先にClientSimで自分1人の動きを確かめてください。 自分の画面でも動いていないなら、同期の問題ではありません。

実践:動かないボタンを3往復で直す

わざと3か所を壊したボタンを作って、順番に見つけていきます。実際の制作でも、この3つが原因の大半です。

3回の一往復で、原因が1つずつ見つかる

1. わざと壊れたボタンを作る

床のあるシーンに、AnimatorとUdonで扉を動かす と同じ扉を用意します。DoorPivot にAnimatorがあり、IsOpen というBoolのパラメータがある状態です。

「Create Empty」で DoorButton を作り、扉のそばに置きます。Cubeではなく空のオブジェクトです。 ここが1つ目の仕込みです。

Assets/ScriptsDebugDoorButton を作ります。

using UdonSharp;
using UnityEngine;

[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class DebugDoorButton : UdonSharpBehaviour
{
    [SerializeField] private Animator doorAnimator;
    [SerializeField] private bool locked = true;   // 2つ目の仕込み

    private bool isOpen;

    public override void Interact()
    {
        Debug.Log("[DoorButton] 押された");

        if (locked)
        {
            Debug.Log("[DoorButton] 鍵がかかっている");
            return;
        }

        Debug.Log("[DoorButton] animatorがある: " + (doorAnimator != null));

        isOpen = !isOpen;
        doorAnimator.SetBool("IsOpen", isOpen);
    }
}

DoorButton に Udon Behaviour を追加して、このスクリプトを指定します。Door Animatorは空のままにしておきます。 これが3つ目の仕込みです。

2. 1往復目:入口のログが出ない

Playして、DoorButton があるはずの場所に近づきます。

そもそもインタラクトの表示が出ません。 Consoleにも何も出ません。

入口のログが出ない。ここで見るのは3つです。

見るところこの場合
Colliderが付いているか付いていない
Udon Behaviourが正しいオブジェクトにあるかある
オブジェクトが有効か有効

DoorButton に「Add Component → Box Collider」を追加して、Sizeを (0.4, 0.4, 0.4) にします。

もう一度Playすると、今度は押せて、[DoorButton] 押された が出ます。押した操作が届くようになりました。

空のオブジェクトにはColliderがありません。Cubeから作れば最初から付いてきます。「押せない」の原因は、たいていここです。

3. 2往復目:入口は出るが、その先に進まない

押すとログは出ますが、扉は動きません。Consoleをよく見ます。

[DoorButton] 押された
[DoorButton] 鍵がかかっている

2行目が答えです。 自分で書いた if で止まっています。

Inspectorで Locked のチェックを外します。これで先へ進みます。

ログを読むときは、最後の1行を見てください。 どこまで進んだかが、そこに書いてあります。

4. 3往復目:進んだのに動かない

もう一度押すと、こう出ます。

[DoorButton] 押された
[DoorButton] animatorがある: False

False です。参照が割り当てられていません。

Inspectorの Door Animator に DoorPivot をドラッグします。

押すと、扉が開きます。

往復症状原因
1ログが出ないColliderがない
2途中で止まる自分で書いた if
3最後まで来るのに動かない参照が None

この3つで、動かないボタンの原因の大半が説明できます。 順番に見ていけば、どれかで必ず引っかかります。

5. ログを片付ける

直ったら、ログを消すか減らします。全部残すとConsoleが埋まって、次に困ったときに読めなくなります。

残すなら、エラーになりうるところだけ にします。

if (doorAnimator == null)
{
    Debug.LogWarning("[DoorButton] Door Animatorが未設定です");
    return;
}

Debug.LogWarning は黄色いアイコンで表示されるので、普通のログに埋もれません。「あとで自分が困るところ」に置いておく と、次のときに助かります。

Sponsored

ログが出ないときは

  • Consoleに何も出ない → Playする前に赤いエラーがないか確認します。コンパイルが通っていません
  • 同じログが1回しか出ない → ConsoleのCollapseがオンです。オフにします
  • 押せない → Colliderがないか、Is Triggerがオンになっています。インタラクトには通常のColliderが要ります
  • 近づかないと押せない → インタラクトには距離の制限があります。もっと近づきます
  • Pickupを付けたら押せなくなった → 掴む操作が優先されます。押す物と掴む物は分けます
  • UIのボタンが反応しない → Interactではなく、CanvasのOn Clickの設定とVRC Ui Shapeを見ます
  • ビルドしたワールドでだけ動かない → ここで初めて同期と所有権を疑います

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

  • VRChatの中のログはファイルに残る: Consoleは見られませんが、クライアントがログを書き出しています。WindowsならAppDataのLocalLowにあるVRChatのフォルダに、テキストで残ります。アップロード後にしか起きない問題は、ここを見ます
  • ログにはタグを付ける: [DoorButton] のように名前を付けておくと、Consoleの検索欄で絞り込めます。仕掛けが増えたときに効いてきます
  • 値も一緒に出す: 「通った」だけでなく、"count=" + count のように値を添えると、次の一往復が省けます
  • 1つずつ直す: 3か所まとめて直すと、どれが効いたか分かりません。1つ直して、試して、次へ進みます
  • ワールド内に表示する手もある: TextMeshProに状態を出すと、VRChatの中でも見えます。同期の確認では、この方法が便利です

まとめ

直し方の順番は、いつも同じです。

  • メソッドの先頭にログを1行置く
  • 出ないなら、押した操作が届いていない。中身は読まない
  • 出るなら、参照・条件・同期を順に見る
  • 確かめる場所は、何を知りたいかで選ぶ

困ったときの問いかけは、「入口のログは出ているか」 です。ここに答えられれば、探す範囲はもう半分になっています。

Udonで書けないC#に出会ったら Udonで使えるC#と使えないC#、症状から探すなら 困ったときの逆引き へ進んでください。

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