🎓 Unityにおけるキャラクターの重力挙動と物理法則の関係
〜 CharacterController.Move()
と運動方程式の対応 〜
📘 概要
Unityでキャラクターを動かす際に用いる CharacterController.Move()
メソッドは、物理エンジン(Rigidbody)を使用しない「スクリプトによる直接制御」の方法です。
この処理の中で、重力をどのようにシミュレートするかは重要な設計ポイントです。本資料では、Physics.gravity
を使った重力処理が、高校物理の運動方程式にどのように対応しているかを解説します。


🧪 使用コード例:Physics.gravity
を用いた移動
void Update()
{
// 入力による移動
Vector3 move = transform.right * Input.GetAxis("Horizontal")
+ transform.forward * Input.GetAxis("Vertical");
controller.Move(move * speed * Time.deltaTime);
// 重力処理
if (controller.isGrounded && velocity.y < 0)
velocity.y = -2f; // 接地補正
velocity += Physics.gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
velocity.y = -2f;
というコードは一見すると謎ですよね。「なんで 0 じゃなくて -2?」「戻されるってどういうこと?」という疑問、しっかり解説します。
🎯 結論:これは「接地補正」であり、キャラクターが地面に張り付くようにするためのテクニックです。
完全に 0 にすると地面から離れて「ピョコピョコ浮く」ような不安定な挙動が起きることがあるため、あえて少しだけ負の値を与えて地面に押しつける目的です。
🔎 詳しく解説:velocity.y = -2f;
の意味
if (controller.isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
◉ なぜ 0
ではなく -2f
なのか?
- Unityの
CharacterController
は、isGrounded
がtrueでも、わずかに浮いてる状態で判定されることがあります。 velocity.y = 0
にすると、そのフレームは地面にいるけど、次のフレームでわずかに浮いてまた落下判定になるという「バウンド現象」が起きやすくなります。
➡ それを避けるために、軽く押さえつけるように -2f
(または -0.1f
など)を入れて「確実に接地」させるのです。
◉ キャラクターは Y=0 に戻るのか?
CharacterController.Move()
を使っている限り、キャラクターはY=0(地面)より下にめり込まないように自動で制御されます。- つまり、
velocity.y = -2f
だとしても、地面に接しているならそれ以上は落下しません。
🧠 イメージで言うと…
velocity.y = 0
→「落下していない、でもギリ浮いてる可能性がある」velocity.y = -2f
→「落下してるっぽく見せて、しっかり接地させている」
✅ まとめ
設定 | 意図 |
---|---|
velocity.y = 0 | 静止に近いが、浮きやすく不安定な挙動になることも |
velocity.y = -2f | 地面に張り付きやすく、接地判定が安定する |
この値は実は「-2」にこだわる必要はなくて、ゲームの規模や設計によって -0.1f
や -5f
などでもOKです。ただし、大きすぎるとジャンプ直後に強く叩きつけられるようになるので注意が必要です。
🧮 物理法則との対応
Unityのコード処理 | 対応する物理公式 | 説明 |
---|---|---|
velocity += gravity * dt | v = v₀ + g * t | 重力加速度による速度変化 |
controller.Move(velocity * dt) | s = v * t | 現在の速度による移動距離の計算 |
接地時の velocity.y = -2f | 現実の「地面との反発・摩擦」表現 | 落下し続けるのを防ぐ、接地補正 |
📊 CharacterController
vs Rigidbody
特徴 | CharacterController | Rigidbody(物理ベース) |
---|---|---|
重力処理 | スクリプトで手動加算 | useGravity により自動適用 |
摩擦や跳ね返り | なし(手動で制御) | 物理マテリアルによる自動調整 |
処理負荷 | 軽い | 高い(特に複雑な衝突時) |
向いている用途 | プレイヤーキャラ制御など | 物理表現中心のゲーム(箱転がし等) |
🌍 Physics.gravity
を使う利点
- グローバルに統一された重力設定を利用できる
- 方向(ベクトル)付きのため、斜めや逆重力の表現が可能
- 他の物理挙動(Rigidbody落下など)と整合が取れる
- メンテナンス・保守がしやすく、見通しの良いコードに
✅ まとめ
- Unityの
CharacterController
でも、物理法則に基づいた重力処理が実現できる velocity += Physics.gravity * dt
は、加速度による速度の変化をシンプルに表現Move(velocity * dt)
で、現在の速度に基づいた移動量を適用Physics.gravity
を使えば、現実的な挙動と一貫性あるゲーム設計が可能
📎 応用アイデア
Physics.gravity = new Vector3(0, -3f, 0)
で月面風ステージPhysics.gravity = Vector3.zero
で宇宙空間new Vector3(-9.81f, 0, 0)
で横方向重力のステージなども実現可能!
ディスカッション
コメント一覧
まだ、コメントがありません