部屋に小物を並べました。 テーブルの上のコップ、床のボール、棚の置物。どれも投げて遊べるようにしてあります。
見た目は良いのに、なぜか重い。誰も触っていない、何も動いていない部屋なのに、フレームレートが伸びません。
転がり終わった物にも、計算は走り続けています。 この記事では、それを止める2つの方法を扱います。
この記事でわかること
- 止まった物を眠らせる仕組み
- 眠らない原因と、その潰し方
- レイヤーで衝突の組み合わせを減らす方法
- Mesh Colliderを避ける理由
当たり判定の基本 と 重さを測る を読んだ状態から始めます。
止まっている物も、計算されている
Rigidbodyが付いている物は、毎回「次はどこへ動くか」を計算されています。床に落ちて止まったあとも、放っておけば計算は続きます。
そのための仕組みが スリープ です。

動きがごく小さい状態がしばらく続くと、Unityはその物を眠らせます。眠っているあいだ、計算はほとんど行われません。何かがぶつかったり、力が加わったりすると自動で起きます。
うまくいけば、置いてあるだけの小物は全部眠ります。 20個並べても、動いていなければ負荷はごくわずかです。
問題は、眠らない物がまざっていること です。原因はだいたい3つに絞れます。
| 原因 | 何が起きているか |
|---|---|
| わずかな斜面に乗っている | ほんの少しずつ滑り続けている |
| コライダーが少し重なっている | 押し返され続けて震えている |
| スクリプトが毎フレーム触っている | 動かされるので、眠る条件に入らない |
見分け方はあとで作ります。まず、「置いてある物が眠っているか」を疑う目 を持ってくださ い。ここが分かるだけで、物理の負荷は大きく変わります。
ぶつかる相手を減らす
もう1つの方法は、組み合わせを減らすこと です。
物理は「どれとどれがぶつかるか」を総当たりで調べます。数が増えるほど、組み合わせは急に増えていきます。

ここで使うのが レイヤー です。オブジェクトに名札を付けて、「この名札とこの名札はぶつからない」と決められます。
飾りのコップ同士がぶつかる必要はあるでしょうか。壁に貼った看板が、床のボールとぶつかる必要は。多くの飾りは、床とだけぶつかれば十分です。
設定は「Edit → Project Settings → Physics」の Layer Collision Matrix で行います。格子状のチェックボックスで、どの組み合わせを調べるかを決めます。
注意が1つあります。VRChatが使っているレイヤーの設定は変えないでください。
| レイヤー | 触ってよいか |
|---|---|
Player PlayerLocal Pickup Walkthrough MirrorReflection など | 触らない |
| 22番以降の空いている番号 | 自由に使える |
自分で作ったレイヤー同士の組み合わせなら、安心して切ったりつないだりできます 。
実践:小物の多い部屋を軽くする
小物を並べた部屋で、眠っているかを確かめて、レイヤーで組み合わせを減らします。
1. 小物を並べて、測る
床のあるシーンに、Sphereを20個ほど並べます。それぞれに Rigidbody を追加して、(0, 1.2, 0) あたりから少しずつずらして置きます。
Playして、全部が床に落ち着くのを待ちます。そのあとProfilerを開いて、Physics関連の帯の太さ を控えます。数字を正確に読む必要はありません。太さを覚えておけば十分です。
2. 眠っているかを見る
眠っているかどうかは、見た目では分かりません。確かめる道具を作ります。

World Space の Canvas と TextMeshPro を置いて SleepText と名付け、Assets/Scripts で SleepWatcher を作ります。
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 / 20 | 3個が眠れずにいる。原因を探します |
この記事でいちばん大事な数字です。 落ち着いて見えるのに数が減らないなら、どこかで震え続けています。
このスクリプトは
Update()を使っています。測るための道具なので構いませんが、確かめ終わったら必ず外してください。 これ自体が負荷になります。
3. 眠らない物を直す
数が0にならなければ、上から順に試します。
- 床が水平か確かめる → Rotationがすべて
0か見ます。わずかな傾きでも滑り続けます - 重なりを解く → Sceneビューで、物同士や床にめり込んでいないか見ます。少し浮かせて置き直します
- 触っているスクリプトを外す → 位置や速度を毎フレーム書いている処理がないか探します
直したら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の帯の太さ |
小物同士がすり抜けることを許せるかどうかは、ワールド次第です。 飾りなら問題ありません。積み上げて遊ぶ物なら、この設定は使えません。
軽さと手ざわりは引き換えです。どちらを取るかは、その物が何のためにあるかで決まります。
うまくいかないときは
- 眠っている数が増えない → 床の傾きと、物同士の重なりを見ます。この2つが原因の大半です
- 触ると起きたまま戻らない → まだ微妙に動いています。摩擦の設定を見るか、置き場所を変えます
- レイヤーを変えたら掴めなくなった → Pickupに関わるレイヤーを変えています。掴む物は元のままにします
- プレイヤーがすり抜けるようになった → VRChatが使うレイヤーの設定を変えています。元に戻してください
- 小物が床を突き抜ける → 落下が速すぎます。落とす高さを下げるか、床のコライダーを厚くします
- 確認用の表示が重い →
SleepWatcherを外してください。役目は終わっています
おまけ:先に知っておくと良いこと
- Mesh Colliderは重い: 見た目どおりの複雑な形で当たり判定を作るので、計算が増えます。動く物に付ける場合はConvexが必要で、そのときは扱える三角形の数にも上限があります。箱と球とカプセルの組み合わせで代用できないか を先に考えてください
- 飾りにRigidbodyを付けない: 動かないものは、Colliderだけで十分です。「いつか動かすかも」で付けたRigidbodyが、そのまま残っていることがよくあります
- 数が三桁になったら設計を見直す: 数十個までなら、眠らせるだけで足ります。 それを超えるなら、そのすべてが本当に動く必要があるかを考えるほうが早いです
- Fixed Timestepは触らない: 物理の計算間隔を変えると全体の挙動が変わります。触らないのが無難です
- Continuous Collision Detectionは既定のままで: 高速で飛ぶ物のすり抜けを防ぐ設定ですが、計算が増えます。困っていないなら変えません
まとめ
物理を軽くするのは、2つの引き算です。
- 止まった物を眠らせる。
IsSleeping()で数えて確かめる - 眠らない原因は、傾き・重なり・毎フレームの操作の3つ
- レイヤーで衝突の組み合わせを減らす。VRChatのレイヤーは触らない
- Mesh Colliderは避ける。飾りにRigidbodyを付けない
置く前の問いかけは、「この物は、動く必要があるか」 です。答えがノーなら、Rigidbodyは要りません。