Unity CharacterController.SimpleMove を使用したジャンプ実装方法

UnityのCharacterControllerコンポーネントを使用してキャラクターを移動させる際、SimpleMoveメソッドはシンプルな移動処理を提供します。しかし、SimpleMoveは内部で重力を自動的に適用し、垂直方向の制御をサポートしていないため、ジャンプの実装には制限があります。本資料では、SimpleMoveを使用しながらスペースキーでジャンプを実装する方法について解説します。


前提知識

  • CharacterController コンポーネント: Unityにおけるキャラクター移動を管理するためのコンポーネント。物理ベースではない移動制御を提供します。
  • SimpleMove メソッド: キャラクターの移動速度を指定し、内部で重力を適用するシンプルな移動メソッド。垂直方向の移動(ジャンプなど)を直接制御することはできません。
  • Move メソッド: キャラクターの移動ベクトルを明示的に指定し、詳細な移動制御が可能なメソッド。ジャンプなどの垂直移動も実装可能です。

SimpleMove の制約

SimpleMoveメソッドは以下の特徴と制約を持ちます:

  • 自動的な重力適用: 垂直方向の移動は内部的に管理され、開発者が直接制御できません。
  • 速度ベクトルの指定: 水平方向の移動速度を簡単に設定できますが、垂直方向の速度(ジャンプなど)を直接反映することはできません。
  • ジャンプの直接サポートなし: SimpleMove自体にはジャンプ機能が組み込まれていません。

これらの制約により、SimpleMoveを使用してジャンプを実装するには工夫が必要です。


ジャンプ実装のアプローチ

SimpleMoveを使用してジャンプを実装する主なアプローチは以下の2つです:

  1. アプローチ1: SimpleMove での擬似ジャンプ
  • SimpleMoveを維持しつつ、ジャンプのような動きをエミュレートする方法。
  1. アプローチ2: Move メソッドへの切り替え
  • ジャンプを含む詳細な移動制御が必要な場合に、Moveメソッドに切り替える方法。

以下では、各アプローチについて詳しく説明します。


アプローチ1: SimpleMove での擬似ジャンプ

概要

SimpleMoveは垂直方向の移動を直接制御できないため、擬似的にジャンプを表現する必要があります。具体的には、ジャンプ時に一時的に速度を増加させることで、キャラクターが上昇するように見せかけます。ただし、この方法は物理的なジャンプとは異なり、あくまで視覚的な効果に留まります。

実装例

以下は、SimpleMoveを使用してスペースキーでジャンプのような動作を実装する例です。

using UnityEngine;

public class SimpleJumpCharacterMove : MonoBehaviour
{
    public float speed = 6.0f;
    public float jumpSpeed = 8.0f;
    public float gravity = 20.0f;

    private CharacterController controller;
    private Vector3 moveDirection = Vector3.zero;
    private bool isJumping = false;
    private float verticalVelocity = 0.0f;

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

    void Update()
    {
        if (controller.isGrounded)
        {
            // 水平方向の移動
            float moveHorizontal = Input.GetAxis("Horizontal");
            float moveVertical = Input.GetAxis("Vertical");
            Vector3 move = new Vector3(moveHorizontal, 0.0f, moveVertical);
            move = transform.TransformDirection(move);
            move *= speed;

            // ジャンプの入力
            if (Input.GetKeyDown(KeyCode.Space))
            {
                isJumping = true;
                verticalVelocity = jumpSpeed;
            }
            else
            {
                isJumping = false;
                verticalVelocity = 0.0f;
            }

            // 垂直方向の移動を加算
            move.y = verticalVelocity;
        }

        if (!controller.isGrounded)
        {
            // 重力を適用
            verticalVelocity -= gravity * Time.deltaTime;
            moveDirection.y = verticalVelocity;
        }

        // SimpleMoveを使用して移動
        controller.SimpleMove(new Vector3(moveDirection.x, moveDirection.y, moveDirection.z) + move);
    }
}

解説

水平方向の移動:

  • Input.GetAxis("Horizontal")Input.GetAxis("Vertical")で入力を取得し、移動ベクトルを計算。
  • transform.TransformDirectionでキャラクターの向きに基づいて移動方向を調整。

ジャンプの入力検出:

  • スペースキーが押されたときにisJumpingtrueにし、verticalVelocityにジャンプ速度を設定。

重力の適用:

  • キャラクターが地面に接していない場合、verticalVelocityに重力を適用。

SimpleMoveでの移動:

  • 水平方向と垂直方向の移動を合算し、SimpleMoveでキャラクターを移動。

制限事項

  • 物理的な挙動の欠如: この方法では、本格的な物理シミュレーションが行われないため、自然なジャンプ動作には限界があります。
  • 複雑な動きへの対応困難: ダブルジャンプや空中での制御など、複雑なジャンプ動作を実装するのは難しいです。
  • SimpleMoveの制約: SimpleMoveが内部で重力を適用するため、垂直方向の速度を完全に制御することが困難です。

アプローチ2: Move メソッドへの切り替え

概要

SimpleMoveの制約を回避し、ジャンプを含む詳細な移動制御を実現するためには、Moveメソッドに切り替えることを推奨します。Moveメソッドを使用すると、垂直方向の移動を含む全方向の移動を明示的に制御でき、自然なジャンプ動作を実装できます。

実装例

以下は、Moveメソッドを使用してスペースキーでジャンプを実装する例です。

using UnityEngine;

public class MoveWithJumpCharacter : MonoBehaviour
{
    public float speed = 6.0f;
    public float jumpSpeed = 8.0f;
    public float gravity = 20.0f;

    private CharacterController controller;
    private Vector3 moveDirection = Vector3.zero;

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

    void Update()
    {
        if (controller.isGrounded)
        {
            // 水平方向の移動
            float moveHorizontal = Input.GetAxis("Horizontal");
            float moveVertical = Input.GetAxis("Vertical");
            moveDirection = new Vector3(moveHorizontal, 0.0f, moveVertical);
            moveDirection = transform.TransformDirection(moveDirection);
            moveDirection *= speed;

            // ジャンプの入力
            if (Input.GetKeyDown(KeyCode.Space))
            {
                moveDirection.y = jumpSpeed;
            }
        }

        // 重力を適用
        moveDirection.y -= gravity * Time.deltaTime;

        // Moveメソッドで移動
        controller.Move(moveDirection * Time.deltaTime);
    }
}

解説

水平方向の移動:

  • Input.GetAxis("Horizontal")Input.GetAxis("Vertical")で入力を取得し、移動ベクトルを計算。
  • transform.TransformDirectionでキャラクターの向きに基づいて移動方向を調整。
  • 水平方向の速度を設定。

ジャンプの入力検出:

  • スペースキーが押されたときに、moveDirection.yにジャンプ速度を設定。

重力の適用:

  • 毎フレーム、moveDirection.yに重力を適用して垂直方向の速度を調整。

Moveメソッドでの移動:

  • 計算された移動ベクトルをMoveメソッドに渡し、キャラクターを移動。

利点

  • 詳細な移動制御: 水平方向および垂直方向の移動を明示的に制御できるため、自然なジャンプ動作を実現可能。
  • 物理的な挙動のシミュレーション: 重力やジャンプ速度を自由に調整でき、リアルな動きを表現できる。
  • 拡張性: ダブルジャンプや空中制御など、複雑な移動ロジックの実装が容易。

まとめ

CharacterController.SimpleMoveはシンプルな移動処理を提供しますが、ジャンプなどの垂直方向の動きを直接制御することは難しいです。擬似的にジャンプを実装する方法もありますが、物理的な挙動や自然な動きを求める場合には、Moveメソッドへの切り替えが推奨されます。

推奨事項

  • 基本的な移動のみを実装する場合: SimpleMoveを使用して迅速にキャラクターの移動を実装可能。
  • ジャンプや高度な移動制御が必要な場合: Moveメソッドを使用し、詳細な移動ロジックを実装する。

プロジェクトの要件やキャラクターの動作に応じて、適切なメソッドを選択することで、効果的なキャラクター制御を実現できます。