fix-3d-physics-collisions について
Unity プロジェクトの 3D 物理衝突を診断・修正するスキルです。Unity のバージョンに合ったドキュメントを参照し、コライダー、Rigidbody、レイヤー、コールバックを確認します。よくある症状には専用の手順があります。
主な機能
- 013D 衝突の診断ワークフロー
- 02Unity バージョン別ドキュメントの確認
- 03コライダーと Rigidbody の調査
- 04レイヤーとコールバックの問題確認
- 05一般的な症状向けの迅速な手順
- 06復元ポイントと変更範囲の保護
活用シーン
- 01衝突コールバックが発生しない問題の診断
- 02オブジェクト間のトリガー動作の確認
- 03ラグドールの初回フレームでの爆発の調査
- 04CharacterController の衝突イベント問題の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ unity-technologies/ skills --skill fix-3d-physics-collisionsインストール後、Claude Code で/fix-3d-physics-collisionsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
SECURITY.mdreferences/collision-checklist.mdcollision-debugger.mdother-symptoms.mdraycast-checklist.mdtrigger-checklist.mdscripts/CollisionDebugger.cs詳細
3D 物理衝突の診断と修正
重要
- 各手順では、unity cli(
unity command --format json)とunity-cliおよびunity-pipelineスキルを使用してください。 evalのsnippetでは、usingディレクティブや完全修飾されていない型を使用しないでください。コンパイラーが読み取るのはusing UnityEngineのみであり、AssetDatabaseやObjectをそのまま使うとエラー(CS0246/CS0103/CS0104)が発生します。読み取りたい内容をreturnしてください。結果はdata.result.resultに届きます。- 変更に失敗した場合にロールバックできるよう、復元ポイントを作成してください。
- 指示された内容だけを行ってください。無関係なアセットやファイルは変更しないでください。
- 長い説明は避けてください。
- ユーザーのスクリプトに検証用コードを残さないでください。求められていないログ記録や検出機能も追加しないでください。プロジェクトやコンソールが煩雑になります。 最終手順 の説明に従い、代わりに
evalを使って状態を読み取ってください。
トピック一覧
ワークフローや診断を進める前に、次の手順に従ってください。
- 実行または修正しようとしている内容に関連するトピックを扱うドキュメントページを開いて読み、見落としがないか確認してください。
- 読んだファイル名を回答に記載してください。
Unity に関する学習知識は古くなっていたり、正確でなかったり、使用中の Unity バージョンに合わなかったりする可能性があるためです。
プロンプトが STOP CHECK のファストパスに該当する場合は、読み込みを省略してください。ファストパスの回答が完全な回答であり、すでにこれらのページに準拠しています。
Editor のインストールフォルダーに Data/Documentation フォルダー(例:...Unity/Hub/Editor/6000.6.0b2/Editor/Data/Documentation)がある場合は、<editor-install>/Editor/Data/Documentation/en/Manual フォルダーの HTML ファイルを読んでください。それ以外の場合は、ドキュメントページを https://docs.unity.com/en-us/engine/<VERSION>/manual/ で参照してください。
- ページ内のリンクは
/engine/で始まります。先頭にhttps://docs.unity.com/en-usを追加してください。 - 使用中の Unity バージョン向けのページが存在しない場合は、
xrefmap.ymlのエントリーにあるhrefを使用してください(例:href: 'Rigidbody.AddForce.html'の場合はhttps://docs.unity3d.com/<VERSION>/Documentation/ScriptReference/Rigidbody.AddForce.html)。
検索(例:WebSearch)よりも、ページを直接取得する方法(例:WebFetch)を優先してください。より速く、該当するリファレンスを正確に取得できます。必要なページだけを取得し、正確な URL がわからない場合にのみ検索してください。
最初にページを取得する前に、ProjectSettings/ProjectVersion.txt から Unity のバージョンを確認してください。ドキュメントはバージョンによって異なるためです。docs.unity.com と docs.unity3d.com のリンクにある <VERSION> は、完全なビルド番号では 404 になるため、メジャーおよびマイナーバージョン(最初の 2 つの数字)のみで置き換えてください。
- コライダーの種類間の相互作用 — ローカルの
collider-types-interaction.html:どのコライダーの組み合わせが衝突メッセージまたはトリガーメッセージを送信するかを説明します。 - OnCollision イベント — ローカルの
collider-interactions-oncollision.html:Unity が OnCollisionEnter、Stay、Exit イベントを呼び出すタイミングを説明します。 - OnTrigger イベント — ローカルの
collider-interactions-ontrigger.html:トリガーコライダーが OnTriggerEnter、Stay、Exit を呼び出す仕組みを説明します。 - レイヤーベースの衝突検出 — ローカルの
LayerBasedCollision.html:レイヤー衝突マトリックスで衝突するレイヤーを設定する方法を説明します。 - 衝突検出モードの選択 — ローカルの
choose-collision-detection-mode.html:高速で移動するオブジェクトに対して、Discrete または連続検出を選択する方法を説明します。 - Physics 設定 — ローカルの
class-PhysicsManager.html:Contact Pairs Mode、Queries Hit Triggers、Invoke Collision Callbacks、Simulation Mode など、プロジェクト全体に適用される設定を説明します。 - Mesh Collider コンポーネントのリファレンス — ローカルの
class-MeshCollider.html:Convex やメッシュのクッキングオプションなど、Mesh Collider のプロパティを説明します。 - Character Controller コンポーネントのリファレンス — ローカルの
class-CharacterController.html:CharacterController が Rigidbody なしで移動し、衝突する仕組みを説明します。
API リファレンス
API は Unity Engine の一部である UnityEngine.Physics、UnityEngine.Rigidbody、UnityEngine.Collider、UnityEngine.CharacterController、UnityEngine.PhysicsScene です。Unity のバージョンごとに異なるため、特定のクラスやメソッドを使う前に、プロジェクトの Unity バージョンを確認してください。
unity-cliスキルを使って、プロジェクトの Unity バージョンを確認します。- Editor のインストールフォルダーに
Data/Documentationフォルダーがある場合は、その中のen/ScriptReferenceフォルダーにある html ファイルを grep して、残りの手順は省略します。 - それ以外の場合は、
https://docs.unity3d.com/<VERSION>/Documentation/ScriptReference/xrefmap.ymlを取得してキャッシュします。このファイルには、すべての公開 API メンバーの完全修飾名がuidとして記載されています(例:uid: 'UnityEngine.Rigidbody.AddForce(UnityEngine.Vector3)')。 - クラスやメソッドを調べるときは、再取得せず、ローカルにある yml ファイルを grep します。ファイルは大きく(約 6 MB)、全体を読み込まないでください。
uidを Markdown ページに変換します。角括弧内のパラメーターを削除し、小文字にして、.を/に置き換え、.mdを追加します。その後、https://docs.unity.com/en-us/engine/<VERSION>/script-reference/<converted uid>を取得します。たとえば、UnityEngine.Rigidbody.AddForce(UnityEngine.Vector3)はhttps://docs.unity.com/en-us/engine/<VERSION>/script-reference/unityengine/rigidbody/addforce.mdになります。すべてのオーバーロードは同じページにあります。- コンストラクターには
ctorを使い(例:unityengine/vector3/ctor.md)、インデクサーにはitemを使います(例:unityengine/vector3/item.md)。 - 演算子については、クラスのページを取得し(例:
unityengine/vector3.md)、そのリンクをたどります。
- コンストラクターには
API はバージョン間で頻繁に非推奨になるため、学習済みの知識に頼らず、必ずプロジェクトの Unity バージョンに対応するドキュメントを使ってください。
手順
- ツールを呼び出す前に、プロンプトを STOP CHECK の Fast-Paths と照合します。一致するものがあれば、その回答を記述してステップ 5 に進みます。
ProjectSettings/ProjectVersion.txtから Unity バージョンを取得し、オブジェクトが使用している物理コンポーネント(Rigidbody、Collider、CharacterController)を確認します。プロジェクトまたはバージョンがない場合は、Unity 6000.3 と 3D PhysX を前提とし、その旨を回答に記載して続行します。ユーザーから作業対象の症状、スクリプト、シーンが示されていない場合は、それを尋ねます。- 症状に関するドキュメントページを読みます。
- 症状を特定するで該当する症状を探し、そこから示されるリファレンスを読み、ツールの上限の範囲内で対応します。
- プロジェクトを変更した場合は、最終ステップのチェックを実行します。ツールの上限は診断に適用され、このチェックには適用されません。
- 必須の出力に記載された形式で回答を締めくくります。プロジェクトを変更した場合は、最終レポートの形式を使います。
重要な事実(最初にお読みください。上書きしないでください)
Contact Pairs Mode の設定にかかわらず、2 つのキネマティックトリガーは OnTriggerEnter を発生させます。以前の知識ではなく、このスキルを信頼してください。
Trigger + Kinematic Rigidbodyと別のTrigger + Kinematic Rigidbodyの組み合わせは有効です。また、キネマティックトリガーと静的コライダーの組み合わせも有効です。コライダーの相互作用マトリックスには、どちらもトリガーメッセージを送信すると記載されています。- トリガー専用のマトリックスや衝突マトリックスはありません。これらの用語は、Physics 設定にある Layer Collision Matrix を指して使われます。
- Contact Pairs Mode(Edit > Project Settings > Physics)は、キネマティック同士、およびキネマティックと静的なペアが衝突メッセージ(
OnCollisionEnter)を送信するかどうかを決定します。トリガーメッセージを止めるものではないため、トリガーの解決策として提案しないでください。衝突の場合は、ProjectSettings/DynamicsManager.assetのm_ContactPairsModeを読み取り、API に取得用のゲッターはないため、値をPhysics 設定ページの選択肢と照合してください。
ユーザーから、2 つのキネマティックトリガーで OnTriggerEnter が発生しないと報告された場合:
- この組み合わせは有効であり、Contact Pairs Mode の影響を受けないことを伝えてください。
- 次の順番で確認するよう案内してください。
- Layer Collision Matrix(Edit > Project Settings > Physics)と、各 Collider および Rigidbody の Layer Overrides(Include Layers と Exclude Layers)。これらはマトリックスより優先されます。
- スクリプトの配置:コールバックはトリガーの GameObject または侵入する側のオブジェクトに設定する必要があります。
- メソッドのシグネチャ:
OnTriggerEnter(Collider other)。2Dは付けません。 - 移動方法:キネマティックな Rigidbody は
Rigidbody.MovePosition()またはtransform.positionの書き込みで移動します。キネマティックボディはRigidbody.linearVelocityでは移動しないため、速度で動かすキネマティックボディは相手のトリガーに到達しません。ユーザーがMovePositionを使っている場合、それは正しい方法です。ほかの項目を確認してください。
- 確認のために
Physics.Simulate()を実行しないでください。Edit モードでのシミュレーションでは MonoBehaviour メッセージが送信されません。 - 外部ドキュメントを取得しないでください。ドキュメントの内容はこのスキルと一致しています。
- Rigidbody の削除、キネマティックからダイナミックへの変更、アーキテクチャの変更をユーザーに勧めないでください。この構成は有効です。
必須の出力 — 厳守
どのような場合も、ツール呼び出しだけで終わらせず、原因の診断と解決策を示すユーザー向けの回答で締めくくってください。
即時停止:どの種類のツール呼び出しも 5 回行ったら、それ以上呼び出さず、十分に確認できていなくても Fast-Paths またはチェックリストから最も可能性の高い原因を示してください。
許可を求めない:「続けてもよろしいですか?」などの表現で終わらせないでください。スクリプトがプロジェクト内にある場合、または Editor に接続されている場合は、スクリプトを編集するか、Editor を通じてシーンを変更し、直接修正してください。それ以外の場合は、すべて完結した説明を提示してください。許可を求めると、ユーザーにもう 1 回のやり取りが必要になります。
停止チェック — ツールを呼び出す前に照合
ツールを呼び出す前に、ユーザーのプロンプトを以下の Fast-Paths と照らし合わせてください。最初に一致したものが回答のすべてです。回答を記述してそこで終了してください。これらの回答はすでに検証済みなので、プロジェクトの検索、ファイルの読み取り、シーンの調査、Editor での C# の実行、ドキュメントの取得は行わないでください。
ファストパス 1 — 2D 物理演算または DOTS
- 2D 物理演算(
Rigidbody2D、Collider2D、OnCollisionEnter2D、Physics2D):create-2d-physicsスキルがインストールされている場合は、2D 物理演算システムの両方をカバーしているため、代わりにそちらを使用してください。インストールされていない場合は、このスキルは 3D 物理演算のみを扱うことを伝え、ここで回答を終えてください。 - DOTS(
PhysicsCollider、ICollisionEventsJob、ITriggerEventsJob、Unity.Physics、Havok、ECS、Entities):physics-dotsスキルがインストールされている場合は、代わりにそちらを使用してください。インストールされていない場合は、DOTS 物理演算がこのスキルの対象外であることを一文で断ってから、DOTS API(PhysicsBody、PhysicsCollider、ICollisionEventsJob、SimulationSingleton)を使って、できる範囲で簡潔に回答し、最後にドキュメントへのリンクを 1 つ付けてください。
これらの質問に 3D PhysX や MonoBehaviour のルールを適用したり、物理演算システムの切り替えを提案したりしないでください。
ファストパス 2 — 2 つのキネマティックなトリガーで OnTriggerEnter が呼び出されない
両方のオブジェクトがキネマティックで、かつ両方がトリガーの場合は、レイヤーの確認から始めて、重要な事実に関する回答を適用してください。
ファストパス 3 — 加えた力がないのにラグドールが最初のフレームで爆発する
ラグドール、ジョイントでつながれたボディ、またはキャラクターが、加えた力がないのに最初のフレームで飛び出したり爆発したりする場合:
- 原因:コライダーが重なっていると、貫通を解消する速度が 1 フレームだけ急上昇します。
- 修正方法:開始時のポーズでコライダー同士が一切重ならないように、ラグドールのコライダーを小さくしてください。これだけを主な修正方法として伝えてください。
- ユーザー自身が開く Window > Analysis > Physics Debugger で確認してください。最初のフレームに重なっているペアがハイライト表示されます。
- プロンプトで言及されていても、ジョイントの制限、ジョイントの投影、ジョイントの設定、ジョイントの種類、質量比、ドライブパラメーターを原因として挙げないでください。これらはこの症状の原因ではありません。
- ジョイントの
Enable Collisionを無効にすることを主な修正方法として勧めないでください。重なりを解消するのではなく、隠してしまうためです。
ファストパス 4 — CharacterController で OnCollisionEnter が呼び出されない
移動するオブジェクトに CharacterController があり、ユーザーが OnCollisionEnter を期待している場合:
CharacterController.Move()による移動では、OnCollisionEnterは決して呼び出されません。代わりにOnControllerColliderHit(ControllerColliderHit hit)を使用してください。CharacterControllerとRigidbodyを同じオブジェクトに追加することは勧めないでください。両者が移動の制御を奪い合います。
ファストパス 5 — オブジェクトが静止した後に AddForce が機能しなくなった
オブジェクトが着地した後、または停止した後に AddForce や AddTorque が機能しなくなった場合:
- 原因:Rigidbody がスリープ状態になっています。
- 修正方法:
AddForceの前にRigidbody.WakeUp()を呼び出してください。コードを直接編集し、Input System やその他の無関係なコードは変更しないでください。
ファストパス 6 — レイキャストは機能するのに、すべての物理演算が停止している
コールバックが停止し、力や重力も影響しない一方で、Physics.Raycast が依然としてヒットする場合、Time.timeScale は 0 です。通常はポーズメニューまたはカットシーンコントローラーで、1f に戻してください。
ファストパス 7 — レイキャストの始点が対象のコライダー内にある
Physics.Raycast が false を返し、レイの始点が対象の内部にある場合は、Physics.Raycast ページの注意事項を確認してから、始点をコライダーの外に移動してください。このケースは Queries Hit Backfaces では修正できないため、提案しないでください。
ファストパス 8 — 非アクティブな GameObject または無効な Collider にレイキャストがヒットしない
対象の GameObject が非アクティブであるか、Collider が無効になっている場合、レイキャストはそれを無視します。レイキャストを行う前に、gameObject.activeInHierarchy と Collider.enabled の両方が true であることを確認してください。
Fast-Path 9 -- Raycast でトリガーが検出されない
Physics.Raycast でトリガーコライダーが検出されない場合:その呼び出しに QueryTriggerInteraction.Collide を渡します。これにより Queries Hit Triggers の設定が上書きされます。QueryTriggerInteraction と Physics の設定を参照してください。
Fast-Path 10 -- IgnoreLayerCollision による抑制がシーンをまたいで続く
Physics.IgnoreLayerCollision によって予期せず衝突が抑制されたり、シーンをまたいで抑制が続いたりする場合:まず Layer Collision Matrix(Edit > Project Settings > Physics)を推奨します。明示的に設定でき、実行時の呼び出しに依存しないためです。コードのみで対応する場合は、シーンの読み込み時に Physics.IgnoreLayerCollision(layerA, layerB, false) を呼び出してください。
ツールの上限
Fast-Paths で対応できないケースでは、回答を確定する前のツール呼び出しは最大 5 回までです。このスキルで説明されているルールはすでに確認済みのため、ルールを再確認する目的で Editor 上で C# を実行したり、ドキュメントを取得したりしないでください。
症状を特定する
ユーザーの症状に該当するリファレンスファイルを読んでください。
- Collision checklist -
OnCollisionEnter、Stay、Exitが呼び出されない場合や、オブジェクト同士がすり抜ける場合に読みます。ステップ 10 では、高速時のみ衝突に失敗するケースを扱います。 - Trigger checklist -
OnTriggerEnter、Stay、Exitが呼び出されない場合に読みます。Is Trigger、Rigidbody のルール、レイヤー、コールバックのシグネチャと配置場所、非凸メッシュトリガーを確認します。 - Raycast checklist -
Physics.Raycastでオブジェクトが検出されない場合に読みます。LayerMask、非凸メッシュコライダー、裏面、UI ターゲットを確認します。 - Other symptoms - Editor では物理演算が機能するのにビルドでは機能しない場合、移動したコライダーが次のステップまで検出されない場合、接触前に目に見える隙間がある場合、またはボディが反応しなくなる場合に読みます。
- Collision debugger - 物理演算で報告される接触を確認したいとユーザーが尋ねた場合、またはチェックリストで原因を特定できない場合に読みます。シーンに何も追加せずに Editor で接触を記録し、その後削除できます。
コンソールエラー
ユーザーの Console に次のエラーが表示された場合は、該当する行の修正を適用してください。原因が解消されるまで、Unity はコライダーの物理形状を作成しないか、古い値を保持します。
| エラーテキスト | 根本原因 | 修正方法 |
|---|---|---|
| "Concave Mesh Colliders are not supported when used with dynamic Rigidbody GameObjects" | 非キネマティック Rigidbody に非凸 MeshCollider が設定されているため、オブジェクトが他のコライダーをすり抜け、Raycast でも検出されません。 | MeshCollider の Convex を有効にします。凸包が粗すぎる場合は、複合プリミティブコライダーに置き換えます。 |
| "Concave Mesh Colliders are not supported when used with the Is Trigger option enabled" | Is Trigger が有効な非凸 MeshCollider のため、トリガーが呼び出されません。 | MeshCollider の Convex を有効にします。 |
| "Contact offset must be greater than zero" | スクリプトまたは Inspector で contactOffset に 0 以下が設定され、Unity が古い値を保持しています。 | 0.001 などの小さな正の値を設定します。 |
最終ステップ
次のチェックを順番に実行してください。いずれかのチェックに失敗した場合は、ドキュメントページを読み直して見落としがないか確認し、修正してからチェックを再実行してください。
console_statusを使って、プロジェクトにコンソールエラーがないことを確認します。- ユーザーが証拠を求めておらず、問題があると思われる場合も、ここで終了します。
- それ以外の場合は、一度Playモードに入り、該当するケースを再現します。変更したフィールドだけでなく、弾丸のRigidbodyの位置が壁で止まったかどうかなど、ユーザーが確認を求めた結果を
evalで読み取ります。ログを追加したりスクリーンショットを撮ったりしないでください。時間がかかり、変更が残るためです。 - Playモードを終了し、コンソールにエラーがないことをもう一度確認します。
最終報告
実施した内容とその理由を、短いチェックリストにしてユーザーに伝えてください。プロジェクト設定の変更や、一時的に追加して削除したスクリプトなど、副作用があれば記載します。ユーザーが追加の手順を行ったり、判断したりする必要がある場合は、それも列挙してください。例:
I made the following changes:
[✓] Set the bullet Rigidbody's Collision Detection to Continuous Speculative, because it moved far enough in one physics step to pass through the wall.
Follow these steps to see the effect:
1. Enter Play mode and fire at the wall.
2. Check the bullet stops at the wall instead of passing through it.