CharacterContollerを使ったキャラクタをジャンプさせる

CharacterControllerコンポーネントは、ジャンプ機能を持っていないので、自作します

シーンの構成

DummyGravitySampleでプロジェクトを作成します

次の図を参考にシーンを作成しましょう

コード

Capsule ゲームオブジェクトにアタッチするコードを考えていきます

CharacterContollerコンポーネントを取得

コンポーネントの取得は色々な方法がありますが、今回は、GetComponentメソッドを使った方法にします
書籍で使われているケースが多いパターンです

CharacterController controller;

void Start()
{
    controller = GetComponent<CharacterController>();
}

地上かどうかチェック

isGroundedプロパティは、地上の場合true、空中の場合falseが入ります
地上の時だけジャンプしたい時、このブロックに処理を記述します

// キャラクタが地上の場合
if (controller.isGrounded)
{
    // 処理
}

重力のシミュレート

Rigidbodyを使わないので、Y軸に下向きの速度を加えます

Physics.gravity.yは、editメニュー、ProjectSetting…で確認することができます。変更も可能です(月の重力の場合1/6でしょうか)

moveVelocityY += Physics.gravity.y * Time.deltaTime;

は、次のコードと同等です
Updateメソッドに記述することになります

moveVelocityY = moveVelocityY + Physics.gravity.y * Time.deltaTime;

Jumpボタンを押されていない時、重力分の速度を加えます
Physics.gravity.yは、デフォルトで -9.8fなので+=ですが、引くことになります
Updateメソッドが実行されるたびに速度は減っていきます

書籍でルーレットが徐々に止まる、車が徐々に減速するチュートリアルと原理は同じです

Physics.gravity.y * Time.deltaTime;は、加速度(m/s2) * 時間(s)で 速度が計算できます(m/s)

moveVelocityYは、ジャンプボタンを押されたら0にします

moveVelocityY = 0;

キャラクタの移動(今回は、上方向限定)

CharacterControllerコンポーネントには、Moveメソッドがあります
引数に移動のベクトル(方向と長さ)をセットします
型は、Vector3型です。今回は、y軸計算だけ抜き出していましたので、xとzに0を代入してVector3型とします

controller.Move(new Vector3(0, moveVelocityY, 0) * Time.deltaTime);

これは、次のコードと同等です。

Vector3 moveVelocity = new Vector3(0, moveVelocityY, 0);
controller.Move(moveVelocity * Time.deltaTime);

全体のコード

using UnityEngine;

public class DummyJump : MonoBehaviour
{
    CharacterController controller;

    // 上に進む速度
    float moveVelocityY;

    // ジャンプするときの速度(重力での速度より大きくすると上にジャンプできる
    float jumpPower = 5;

    void Start()
    {
        controller = GetComponent<CharacterController>();
    }

    void Update()
    {
        // Jumpボタンを押されていない時、重力分の速度を加えます
        // Physics.gravity.yは、デフォルトで -9.8fなので+=ですが、引くことになります
        moveVelocityY += Physics.gravity.y * Time.deltaTime;

        Debug.Log(controller.isGrounded);

        // キャラクタが地上の場合
        if (controller.isGrounded)
        {
            // moveVelocityY = 0でいいのですが、接地判定が不安定になる現象があります
            // 接地判定を確実に知るため-0.5fを代入します
            // ちなみに0を代入すると、Debug.Logで表示されているのがtrue、falseとバタつくのがわかります
            moveVelocityY = -0.5f;

            // ジャンプボタンがおされたら(標準はスペースキー)
            if (Input.GetButtonDown("Jump"))
            {
                // Y軸の速度を代入
                moveVelocityY = jumpPower;
            }
        }

        // キャラクタの移動(今回Y軸だけでテスト)
        controller.Move(new Vector3(0, moveVelocityY, 0) * Time.deltaTime);
    }
}

実行結果

スペースキーを押すとジャンプします