【VRChat】物理の負荷を下げる:眠らせて、ぶつける相手を減らす

作成: 2026-09-08最終更新: 2026-09-09

転がり終わった小物が眠っているかを確かめ、眠らない原因を潰します。レイヤーで衝突の組み合わせを減らす方法と、Mesh Colliderを避ける理由も解説します。

部屋に小物を並べました。テーブルの上のコップ、床のボール、棚の置物。どれも投げて遊べるようにしてあります。

見た目は良いのに、なぜか重い。誰も触っていない、何も動いていない部屋なのに、フレームレートが伸びません。

転がり終わった物にも、計算は走り続けています。 この記事では、それを止める2つの方法を扱います。

床に落ち着いた小物が、静かに眠っている

この記事でわかること

  • 止まった物を眠らせる仕組み
  • 眠らない原因と、その潰し方
  • レイヤーで衝突の組み合わせを減らす方法
  • Mesh Colliderを避ける理由

当たり判定の基本重さを測る を読んだ状態から始めます。

Sponsored


止まっている物も、計算されている

Rigidbodyが付いている物は、毎回「次はどこへ動くか」を計算されています。床に落ちて止まったあとも、放っておけば計算は続きます。

そのための仕組みが スリープ です。

動きが小さい状態が続くと眠り、触れると起きる

動きがごく小さい状態がしばらく続くと、Unityはその物を眠らせます。眠っているあいだ、計算はほとんど行われません。何かがぶつかったり、力が加わったりすると自動で起きます。

うまくいけば、置いてあるだけの小物は全部眠ります。 20個並べても、動いていなければ負荷はごくわずかです。

問題は、眠らない物がまざっていること です。原因はだいたい3つに絞れます。

原因何が起きているか
わずかな斜面に乗っているほんの少しずつ滑り続けている
コライダーが少し重なっている押し返され続けて震えている
スクリプトが毎フレーム触っている動かされるので、眠る条件に入らない

見分け方はあとで作ります。まず、「置いてある物が眠っているか」を疑う目 を持ってください。ここが分かるだけで、物理の負荷は大きく変わります。

ぶつかる相手を減らす

もう1つの方法は、組み合わせを減らすこと です。

物理は「どれとどれがぶつかるか」を総当たりで調べます。数が増えるほど、組み合わせは急に増えていきます。

レイヤーを分けると、調べる組み合わせが減る

ここで使うのが レイヤー です。オブジェクトに名札を付けて、「この名札とこの名札はぶつからない」と決められます。

飾りのコップ同士がぶつかる必要はあるでしょうか。壁に貼った看板が、床のボールとぶつかる必要は。多くの飾りは、床とだけぶつかれば十分です。

設定は「Edit → Project Settings → Physics」の Layer Collision Matrix で行います。格子状のチェックボックスで、どの組み合わせを調べるかを決めます。

注意が1つあります。VRChatが使っているレイヤーの設定は変えないでください。

レイヤー触ってよいか
Player PlayerLocal Pickup Walkthrough MirrorReflection など触らない
22番以降の空いている番号自由に使える

自分で作ったレイヤー同士の組み合わせなら、安心して切ったりつないだりできます。

Sponsored

実践:小物の多い部屋を軽くする

小物を並べた部屋で、眠っているかを確かめて、レイヤーで組み合わせを減らします。

1. 小物を並べて、測る

床のあるシーンに、Sphereを20個ほど並べます。それぞれに Rigidbody を追加して、(0, 1.2, 0) あたりから少しずつずらして置きます。

Playして、全部が床に落ち着くのを待ちます。そのあとProfilerを開いて、Physics関連の帯の太さ を控えます。数字を正確に読む必要はありません。太さを覚えておけば十分です。

2. 眠っているかを見る

眠っているかどうかは、見た目では分かりません。確かめる道具を作ります。

起きている数が3から0へ変わる

World Space の Canvas と TextMeshPro を置いて SleepText と名付け、Assets/ScriptsSleepWatcher を作ります。

using UdonSharp;
using UnityEngine;
using TMPro;

// 確認用。確かめ終わったら外す
[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class SleepWatcher : UdonSharpBehaviour
{
    [SerializeField] private Rigidbody[] targets;
    [SerializeField] private TextMeshProUGUI display;

    private void Update()
    {
        int awake = 0;
        for (int i = 0; i < targets.Length; i++)
        {
            if (targets[i] != null && !targets[i].IsSleeping()) awake++;
        }

        if (display != null)
        {
            display.text = "起きている: " + awake + " / " + targets.Length;
        }
    }
}

Targets に20個のRigidbodyをまとめてドラッグします。Hierarchyで複数選択してから、欄にドロップすれば一度に入ります。

Playして、しばらく待ちます。

表示意味
起きている: 0 / 20全部眠っている。理想的です
起きている: 3 / 203個が眠れずにいる。原因を探します

この記事でいちばん大事な数字です。 落ち着いて見えるのに数が減らないなら、どこかで震え続けています。

このスクリプトは Update() を使っています。測るための道具なので構いませんが、確かめ終わったら必ず外してください。 これ自体が負荷になります。

3. 眠らない物を直す

数が0にならなければ、上から順に試します。

  1. 床が水平か確かめる → Rotationがすべて 0 か見ます。わずかな傾きでも滑り続けます
  2. 重なりを解く → Sceneビューで、物同士や床にめり込んでいないか見ます。少し浮かせて置き直します
  3. 触っているスクリプトを外す → 位置や速度を毎フレーム書いている処理がないか探します

直したらPlayし直して、起きている: 0 / 20 になるのを確かめます。

4. レイヤーで組み合わせを減らす

Inspectorの右上「Layer」から「Add Layer...」を選び、22番以降の空いている行WorldProps と入力します。

20個の小物を全選択して、Layerを WorldProps にします。子オブジェクトも変えるか聞かれたら、変えて構いません。

「Edit → Project Settings → Physics」を開き、Layer Collision Matrix で次のようにします。

組み合わせチェック
WorldProps × Default(床)オン
WorldProps × WorldPropsオフ

小物同士がぶつからなくなりました。床には落ちますが、互いをすり抜けます。

5. 測り直す

もう一度Playして、Profilerの帯を見ます。

項目
起きているRigidbody
Physicsの帯の太さ

小物同士がすり抜けることを許せるかどうかは、ワールド次第です。 飾りなら問題ありません。積み上げて遊ぶ物なら、この設定は使えません。

軽さと手ざわりは引き換えです。どちらを取るかは、その物が何のためにあるかで決まります。

Sponsored

うまくいかないときは

  • 眠っている数が増えない → 床の傾きと、物同士の重なりを見ます。この2つが原因の大半です
  • 触ると起きたまま戻らない → まだ微妙に動いています。摩擦の設定を見るか、置き場所を変えます
  • レイヤーを変えたら掴めなくなった → Pickupに関わるレイヤーを変えています。掴む物は元のままにします
  • プレイヤーがすり抜けるようになった → VRChatが使うレイヤーの設定を変えています。元に戻してください
  • 小物が床を突き抜ける → 落下が速すぎます。落とす高さを下げるか、床のコライダーを厚くします
  • 確認用の表示が重いSleepWatcher を外してください。役目は終わっています

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

  • Mesh Colliderは重い: 見た目どおりの複雑な形で当たり判定を作るので、計算が増えます。動く物に付ける場合はConvexが必要で、そのときは扱える三角形の数にも上限があります。箱と球とカプセルの組み合わせで代用できないか を先に考えてください
  • 飾りにRigidbodyを付けない: 動かないものは、Colliderだけで十分です。「いつか動かすかも」で付けたRigidbodyが、そのまま残っていることがよくあります
  • 数が三桁になったら設計を見直す: 数十個までなら、眠らせるだけで足ります。それを超えるなら、そのすべてが本当に動く必要があるかを考えるほうが早いです
  • Fixed Timestepは触らない: 物理の計算間隔を変えると全体の挙動が変わります。触らないのが無難です
  • Continuous Collision Detectionは既定のままで: 高速で飛ぶ物のすり抜けを防ぐ設定ですが、計算が増えます。困っていないなら変えません

まとめ

物理を軽くするのは、2つの引き算です。

  • 止まった物を眠らせる。IsSleeping() で数えて確かめる
  • 眠らない原因は、傾き・重なり・毎フレームの操作の3つ
  • レイヤーで衝突の組み合わせを減らす。VRChatのレイヤーは触らない
  • Mesh Colliderは避ける。飾りにRigidbodyを付けない

置く前の問いかけは、「この物は、動く必要があるか」 です。答えがノーなら、Rigidbodyは要りません。

仕掛けの側を軽くするなら Udonを軽くする、見た目の側なら 描画を軽くする へ進んでください。

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