ゲーム開発でキャラクターの当たり判定を実装しようとすると、様々な形状の選択肢があります。
「キャラクターの当たり判定にはどんな形状がいいの?」
「カプセルって何?」
「どうやって実装するの?」
そんな疑問を抱えている方に向けて、3Dゲームでキャラクターの当たり判定として広く使われているカプセル衝突判定について、初心者でも理解できるように解説します。
\読むだけで終わらせない!実際にゲームを作って実力をつけよう/
トレンド×入門に最適
Unity ノンフィールドRPG
+スレスパ風JRPG講座
Unity6対応・スマホ化対応の最新カリキュラム。今もっとも人気のデッキ構築型ゲームをJRPGと組み合わせて実装。初心者が最初に選ぶ一本として最適です。
王道アクションに挑戦
Unity 2Dアクションゲーム
の作り方講座(ロックマン風)
ロックマン風の本格横スクロールACTをスマホ化・広告実装まで対応。7ステージ+ラスボスという市販ゲームに近い本格構成で、リリースまで見据えて作れます。
3D入門に最適
ゼルダ風3Dアクションゲーム
の作り方講座
ゼルダの伝説・モンハン・原神のような3Dアクションをスマホ対応で作れる入門講座。初心者でも全16回でしっかり3D開発の基礎を習得できます。
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。
カプセルとは何か
カプセルは、円柱の上下に半球を追加した形状です。
ゲーム開発では、キャラクターの当たり判定として非常に人気があります。
AABBや球と比べて、人間の体形に近い形状でありながら、計算も比較的簡単という特徴があるんです。
カプセルの構造
カプセルは、以下の要素で構成されます。
- 中心点:カプセルの中心位置
- 中心軸:カプセルの向き(通常はY軸方向)
- 高さ:円柱部分の高さ
- 半径:円柱と半球の半径
UnityのCapsuleColliderでは、これらのパラメータを設定できます。
なぜカプセルがキャラクターに適しているのか
カプセルがキャラクターの当たり判定として選ばれる理由は、いくつかあります。
人間の体形に近いため、衝突判定の精度が高い。
球よりも高さがあり、AABBよりも角がなく滑らかなため、キャラクター同士がぶつかった時の挙動が自然になります。
また、計算が比較的簡単で、パフォーマンスも良好。
球判定よりも少し計算コストが高いものの、AABBやOBBほど複雑ではありません。
- 円柱の上下に半球を追加した形状
- キャラクターの体形に近く、衝突判定が自然
- 球よりも高さがあり、AABBよりも滑らか
- 計算コストは球より高いが、実用的な範囲内
カプセル同士の衝突判定アルゴリズム
2つのカプセルが衝突しているかを判定する方法を見ていきましょう。
基本的な考え方
カプセル同士の衝突判定は、2つのカプセルの中心軸間の最短距離を計算することで実現できます。
最短距離が2つのカプセルの半径の合計以下であれば、衝突していると判定できます。
この方法は、球の衝突判定を拡張した考え方です。
中心軸間の最短距離
2つのカプセルの中心軸間の最短距離を計算するには、線分と線分の最短距離を求める必要があります。
2つの線分(それぞれのカプセルの中心軸)の最短距離を求め、その距離が半径の合計以下かどうかを判定します。
実装コード例
Unityでカプセル同士の衝突判定を実装する場合、以下のようなコードになります。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
bool CheckCapsuleCollision( Vector3 center1, Vector3 top1, float radius1, Vector3 center2, Vector3 top2, float radius2) { // カプセル1の中心軸ベクトル Vector3 axis1 = top1 - center1; float height1 = axis1.magnitude; Vector3 dir1 = axis1.normalized; // カプセル2の中心軸ベクトル Vector3 axis2 = top2 - center2; float height2 = axis2.magnitude; Vector3 dir2 = axis2.normalized; // 2つの線分の最短距離を計算 float distance = GetLineSegmentDistance( center1, center1 + dir1 * height1, center2, center2 + dir2 * height2); // 半径の合計と比較 return distance <= (radius1 + radius2); } float GetLineSegmentDistance(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4) { Vector3 d1 = p2 - p1; Vector3 d2 = p4 - p3; Vector3 r = p1 - p3; float a = Vector3.Dot(d1, d1); float e = Vector3.Dot(d2, d2); float f = Vector3.Dot(d2, r); if (a <= float.Epsilon && e <= float.Epsilon) { return Vector3.Distance(p1, p3); } if (a <= float.Epsilon) { return Vector3.Distance(p1, p3 + d2 * Mathf.Clamp01(f / e)); } float c = Vector3.Dot(d1, r); if (e <= float.Epsilon) { return Vector3.Distance(p1 + d1 * Mathf.Clamp01(c / a), p3); } float b = Vector3.Dot(d1, d2); float denom = a * e - b * b; float s, t; if (denom != 0) { s = Mathf.Clamp01((b * f - c * e) / denom); } else { s = 0; } t = (b * s + f) / e; if (t < 0) { t = 0; s = Mathf.Clamp01(-c / a); } else if (t > 1) { t = 1; s = Mathf.Clamp01((b - c) / a); } Vector3 closest1 = p1 + d1 * s; Vector3 closest2 = p3 + d2 * t; return Vector3.Distance(closest1, closest2); } |
このコードでは、2つのカプセルの中心軸(線分)の最短距離を計算し、半径の合計と比較しています。
カプセルと球の衝突判定
カプセルと球の衝突判定は、カプセル同士の判定よりも少し簡単です。
基本的な考え方
カプセルと球の衝突判定は、球の中心からカプセルの中心軸への最短距離を計算することで実現できます。
最短距離がカプセルの半径と球の半径の合計以下であれば、衝突していると判定できます。
実装コード例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
bool CheckCapsuleSphereCollision( Vector3 capsuleCenter, Vector3 capsuleTop, float capsuleRadius, Vector3 sphereCenter, float sphereRadius) { // カプセルの中心軸 Vector3 axis = capsuleTop - capsuleCenter; float height = axis.magnitude; Vector3 dir = axis.normalized; // 球の中心からカプセルの中心軸への最短距離 Vector3 toSphere = sphereCenter - capsuleCenter; float projection = Vector3.Dot(toSphere, dir); projection = Mathf.Clamp(projection, 0f, height); Vector3 closestPoint = capsuleCenter + dir * projection; float distance = Vector3.Distance(sphereCenter, closestPoint); // 半径の合計と比較 return distance <= (capsuleRadius + sphereRadius); } |
この方法では、球の中心からカプセルの中心軸上で最も近い点を求め、その距離を半径の合計と比較しています。
カプセルと平面の衝突判定
カプセルと平面(地面など)の衝突判定も、ゲーム開発では重要です。
基本的な考え方
カプセルと平面の衝突判定は、カプセルの中心軸上の各点から平面への距離を計算することで実現できます。
最も近い点の距離がカプセルの半径以下であれば、衝突していると判定できます。
実装コード例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
bool CheckCapsulePlaneCollision( Vector3 capsuleCenter, Vector3 capsuleTop, float capsuleRadius, Vector3 planePoint, Vector3 planeNormal) { // カプセルの中心軸 Vector3 axis = capsuleTop - capsuleCenter; float height = axis.magnitude; Vector3 dir = axis.normalized; // カプセルの中心から平面への距離 Vector3 toPlane = capsuleCenter - planePoint; float centerDistance = Vector3.Dot(toPlane, planeNormal); // カプセルの軸方向の成分 float axisComponent = Vector3.Dot(dir, planeNormal); // 最も近い点を計算 float minDistance = centerDistance - Mathf.Abs(axisComponent) * height * 0.5f; // 半径と比較 return Mathf.Abs(minDistance) <= capsuleRadius; } |
この方法では、カプセルの中心軸上の最も平面に近い点を計算し、その距離をカプセルの半径と比較しています。
Unityでの実装例(C#コード)
Unityでカプセル衝突判定を実装する具体的な例を見ていきましょう。
UnityのCapsuleColliderを使用する方法
Unityには、標準でCapsuleColliderコンポーネントが用意されています。
これを使えば、物理エンジンによる衝突判定が自動的に行われます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
using UnityEngine; public class CapsuleColliderExample : MonoBehaviour { void Start() { // CapsuleColliderを追加 CapsuleCollider capsuleCollider = gameObject.AddComponent(); // パラメータを設定 capsuleCollider.radius = 0.5f; // 半径 capsuleCollider.height = 2.0f; // 高さ capsuleCollider.center = Vector3.zero; // 中心位置 } } |
物理エンジンを使う場合は、Rigidbodyも一緒に使用します。
カスタムカプセル衝突判定クラス
物理エンジンを使わずに、独自の衝突判定を実装する場合の例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
using UnityEngine; public class CustomCapsuleCollider : MonoBehaviour { public float radius = 0.5f; public float height = 2.0f; private Vector3 bottom; private Vector3 top; void Update() { UpdateCapsuleBounds(); } void UpdateCapsuleBounds() { Vector3 center = transform.position; Vector3 up = transform.up; float halfHeight = height * 0.5f - radius; bottom = center - up * halfHeight; top = center + up * halfHeight; } public bool CheckCollision(CustomCapsuleCollider other) { float distance = GetLineSegmentDistance(bottom, top, other.bottom, other.top); return distance <= (radius + other.radius); } private float GetLineSegmentDistance(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4) { // 前のコードと同じ実装 // ... } } |
このクラスでは、Transformからカプセルの境界を計算し、他のカプセルとの衝突判定を行っています。
- CapsuleColliderを使う場合は、物理エンジンの更新タイミングに依存する
- カスタム実装の場合は、毎フレーム更新が必要になる
- カプセルの向きが変わった場合、境界の再計算が必要
- 大量のカプセル間で判定を行う場合は、最適化が必要になる場合がある
カプセル衝突判定の実装手順
※この順番を守らずに作り始めると、だいたい後で全部作り直すことになります。
- STEP1カプセルのパラメータを定義
カプセルの中心点、高さ、半径を定義します。Transformから位置と向きを取得する準備をしましょう。
- STEP2中心軸の計算
カプセルの中心軸(線分)を計算します。上下の端点を求め、方向ベクトルを計算しましょう。
- STEP3最短距離の計算
2つのカプセルの中心軸間の最短距離を計算します。線分と線分の最短距離のアルゴリズムを実装しましょう。
- STEP4衝突判定の実装
最短距離が半径の合計以下かどうかを判定します。衝突が検出された場合の処理も実装しましょう。
- STEP5最適化とテスト
不要な計算を避けるため、距離チェックなどの最適化を行います。実際に動作確認を行い、問題がないか確認しましょう。
よくある問題と解決方法
カプセル衝突判定を実装する際によくある問題と、その解決方法を紹介します。
カプセルの向きが正しく計算されない
カプセルの向きを計算する際、Transformのupベクトルを使用します。
|
1 2 3 4 5 6 7 8 |
// ✅ 正しい実装 Vector3 up = transform.up; bottom = center - up * halfHeight; top = center + up * halfHeight; // ❌ 間違った実装(固定の向き) Vector3 up = Vector3.up; // Y軸固定 |
カプセルが回転する場合は、Transformのupベクトルを使う必要があります。
半径が大きすぎて誤検出が発生する
カプセルの半径を設定する際、実際のオブジェクトのサイズと一致させる必要があります。
半径が大きすぎると、実際には衝突していないのに衝突判定が出てしまいます。
|
1 2 3 |
// オブジェクトのスケールを考慮 float actualRadius = radius * transform.localScale.x; |
Transformのスケールを考慮して、実際の半径を計算しましょう。
パフォーマンスの問題
大量のカプセル間で衝突判定を行う場合、計算コストが高くなります。
Broad PhaseとNarrow Phaseを分けることで、効率化できます。
|
1 2 3 4 5 6 7 8 |
// 距離チェックで事前に除外 float distance = Vector3.Distance(center1, center2); float maxDistance = (radius1 + radius2) + (height1 + height2); if (distance > maxDistance) { return false; // 衝突の可能性がない } |
距離チェックで遠いオブジェクトを除外すれば、不要な計算を削減できます。
- カプセルの向きが合わない → Transformのupベクトルを使用する
- 誤検出が発生する → 半径の設定とスケールを確認する
- パフォーマンスが悪い → Broad PhaseとNarrow Phaseを分ける
- 地面との判定が合わない → 平面との判定アルゴリズムを確認する
カプセルと他の形状との比較
カプセルと他の衝突判定形状との違いを理解しておくと、適切な選択ができます。
カプセル vs 球
| 項目 | カプセル | 球 |
|---|---|---|
| 計算速度 | やや遅い | 非常に高速 |
| 形状の適合性 | キャラクターに適している | 等方的な形状 |
| 高さの表現 | 可能 | 不可能 |
| 実装の難易度 | やや複雑 | 簡単 |
カプセルは球よりも高さを表現できるため、キャラクターに適しています。
カプセル vs AABB
| 項目 | カプセル | AABB |
|---|---|---|
| 計算速度 | やや遅い | 非常に高速 |
| 形状の滑らかさ | 滑らか | 角がある |
| 回転対応 | 対応可能 | 不向き |
| キャラクターへの適合 | 高い | 低い |
カプセルは滑らかな形状のため、キャラクター同士の衝突判定で自然な挙動になります。
- キャラクターの当たり判定 → カプセル
- 等方的なオブジェクト → 球
- 回転しない固定オブジェクト → AABB
- 複雑な形状 → 詳細なポリゴン判定
カプセル衝突判定の学習を深めるには
カプセル衝突判定の基礎を理解した後は、さらに深く学んでいくことが大切です。
Unity入門の森では、ゲーム開発に必要な物理と数学の知識を体系的に学べる環境が整っています。
特に、永久会員チケットでは、衝突判定だけでなく、物理演算やゲーム数学など、関連する知識も幅広くカバーしています。
また、2Dアクションゲーム講座では、実際にゲームを作りながら、衝突判定の実践的な使い方を身につけられます。
当たり判定の基礎から応用まで、実際のコードと紐付けて学べるので、理解が深まりやすいはずです。
- カプセルとは何か、なぜキャラクターに適しているのか
- カプセル同士の衝突判定アルゴリズム
- カプセルと球・平面との衝突判定
- Unityでの実装例(C#コード)
- 他の形状との比較と使い分け
記事を読んで「作ってみたい!」と思ったら!人気ゲームを題材にした講座で実力をつけよう
知識を読むだけで終わらせるのはもったいない。実際に手を動かしてゲームを1本完成させることで、理解が一気に深まります。人気タイトルをモデルにした講座で、ゲーム開発の第一歩を踏み出しましょう。
Unity ノンフィールドRPG+スレスパ風JRPG講座【Unity6対応!トレンドのデッキ構築×JRPGをスマホ向けに作れる!】

- Unity6対応・スマホ化対応で最新環境のゲーム開発が学べる
- Slay the Spire風のデッキ構築システム×JRPGの組み合わせを実装
- 初心者でも取り組みやすい丁寧な解説構成
- ノンフィールドRPGとデッキ構築JRPGの2つを合わせて学ぶのがおすすめ
Unity ノンフィールドRPGの作り方講座+Slay the Spire風デッキ構築JRPGの作り方講座は、今もっともトレンドのデッキ構築型ゲームシステムをJRPGと組み合わせて実装する方法を学べる講座です。
Unity6対応・スマホ化対応の最新カリキュラムで、コラムやTIPSで読んで「なるほど」と思った知識を、実際に動くゲームとして形にする体験ができます。
「Slay the Spireみたいなゲームを自分でも作ってみたい!」という人の最初の一歩として最適な講座です。
Unity6対応・スマホ化対応の最新カリキュラム
トレンドのデッキ構築×JRPGを最速で実装しよう
→ スレスパ風デッキ構築JRPG講座を見てみる
スマホ対応の最新環境で、ゲーム開発の第一歩を踏み出そう!
Unity 2Dアクションゲームの作り方講座(ロックマン風)【全16回!スマホ化・広告実装まで対応した本格横スクロールACTを作れる!】

- ロックマン・マリオ・カービィのような横スクロールACTをゼロから開発
- 7ステージ+ラスボスステージの市販ゲームに近い本格的なゲーム設計
- スマホ化・AdMob広告実装まで対応してリリースまで見据えた構成
- 敵AI15体・多彩なマップギミック・武器システムを完全実装
- 完全オリジナルゲームをアセット不使用で素材提供付きで制作
Unity 2Dアクションゲームの作り方講座(ロックマン風)は、ロックマン・スーパーマリオ・星のカービィのような2D横スクロールアクションゲームを開発できるようになる本格的な講座です。
TIPSやコラムで学んだ当たり判定・物理挙動・敵AIの知識を、実際のゲームコードとして実装する体験が全16回に凝縮されています。スマホ化・広告実装まで対応しているため、作って終わりではなくリリースまで見据えた実践スキルが身につきます。
「読んで理解した知識を、動くゲームとして形にしたい」という人に強くおすすめの一本です。
スマホ化・広告実装まで対応した本格横スクロールACT
ロックマン風の2Dアクションゲームをリリースまで作り上げよう
→ 2Dアクションゲームの作り方講座を見てみる
広告収益まで視野に入れた実践スキルを今すぐ手に入れよう!
ゼルダ風3Dアクションゲームの作り方講座【全16回!初心者でも3Dアクションがスマホ対応で作れる!】

- ゼルダの伝説・モンハン・原神のような3Dアクションをゼロから開発
- 初心者でも取り組みやすい丁寧な解説構成
- スマホ化対応で実機で動かせるゲームが完成
- アセットを使った実践的なゲーム開発手法が身につく
- 画像・動画・全ソースコード公開の充実したサポート
ゼルダ風3Dアクションゲームの作り方講座は、ゼルダの伝説・モンハン・原神のような本格的な3Dアクションゲームを作りたい人におすすめの入門講座です。
コラム・TIPSで「3Dゲームはなんとなく難しそう」と感じていた人でも、全16回の丁寧な解説で確実に完成まで到達できます。スマホ化対応で実機で動かせるため、作った達成感がひときわ大きい講座です。
「3Dゲームの仕組みを理解した次は、実際に自分で作ってみたい」という人の最初の一歩として最適です。
初心者でも3Dアクションがスマホ対応で完成する
ゼルダ風3Dアクションゲームで3D開発の第一歩を踏み出そう
→ ゼルダ風3Dアクションゲームの作り方講座を見てみる
3D開発の壁を一気に突破!スマホで動くオリジナルゲームを完成させよう!
まとめ

この記事では、Unityでカプセル衝突判定を実装する方法を解説しました。
カプセルは、キャラクターの当たり判定として非常に適した形状です。
人間の体形に近く、計算も比較的簡単で、自然な衝突挙動を実現できるのが特徴。
「カプセル判定って難しそう💧」と感じる方もいるかもしれませんが、基本的な仕組みを理解すれば実装できます。
まずはUnityのCapsuleColliderを使った簡単な実装から始めて、徐々にカスタム実装に挑戦していきましょう。
- カプセルは円柱の上下に半球を追加した形状で、キャラクターに適している
- カプセル同士の衝突判定は、中心軸間の最短距離を計算することで実現
- UnityのCapsuleColliderを使えば、物理エンジンによる自動判定が可能
- カスタム実装の場合は、線分と線分の最短距離アルゴリズムが必要
- 大量のカプセル間で判定を行う場合は、最適化が必要な場合がある
まずは簡単な実装から始めて、徐々に応用的な使い方を覚えていきましょう。
Unity入門の森では、衝突判定の基礎から応用まで、実践的な知識を体系的に学べる環境が整っています。
疑問があれば、ぜひ活用してみてください。
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。





コメント