🎓 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 * dtv = v₀ + g * t重力加速度による速度変化
controller.Move(velocity * dt)s = v * t現在の速度による移動距離の計算
接地時の velocity.y = -2f現実の「地面との反発・摩擦」表現落下し続けるのを防ぐ、接地補正

📊 CharacterController vs Rigidbody

特徴CharacterControllerRigidbody(物理ベース)
重力処理スクリプトで手動加算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) で横方向重力のステージなども実現可能!

Unity

Posted by hidepon