Unity の 2D プラットフォーマー キャラクター コントローラーにダブル ジャンプ サポートを追加する

このチュートリアルでは、Unity の 2D プラットフォーマー プレーヤーを、ダブル ジャンプ機能を組み込んで強化します。

この修正ガイドは、Unity 用の 2D キャラクター コントローラーのチュートリアルに既に従っていることを前提としています。

ステップ 1: 変数を宣言する

ダブル ジャンプ機能を管理するには、次の変数を既存のスクリプトに追加します。

public int maxJumps = 2;
int jumpsRemaining;

これらの変数は、許可されるジャンプの最大数 'maxJumps' と残りのジャンプ数 'jumpsRemaining' を追跡します。

ステップ 2: ジャンプ ロジックを変更する

'void Update()' メソッドのジャンプ ロジックを調整して、ダブル ジャンプ機能を実装します。

// Jumping
if (Input.GetKeyDown(KeyCode.W))
{
    if (isGrounded || jumpsRemaining > 0)
    {
        r2d.velocity = new Vector2(r2d.velocity.x, jumpHeight);

        // Reset jumps when grounded
        if (isGrounded)
        {
            jumpsRemaining = maxJumps;
        }
        jumpsRemaining--;
    }
}

この修正により、プレイヤーは接地している場合、またはまだジャンプが残っている場合にジャンプを実行できるようになります。

最終的に変更されたスクリプトを以下で確認してください。

'CharacterController2D.cs'

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(CapsuleCollider2D))]

public class CharacterController2D : MonoBehaviour
{
    // Move player in 2D space
    public float maxSpeed = 3.4f;
    public float jumpHeight = 6.5f;
    public float gravityScale = 1.5f;
    public Camera mainCamera;

    public int maxJumps = 2;
    int jumpsRemaining;

    bool facingRight = true;
    float moveDirection = 0;
    bool isGrounded = false;
    Vector3 cameraPos;
    Rigidbody2D r2d;
    CapsuleCollider2D mainCollider;
    Transform t;

    // Use this for initialization
    void Start()
    {
        t = transform;
        r2d = GetComponent<Rigidbody2D>();
        mainCollider = GetComponent<CapsuleCollider2D>();
        r2d.freezeRotation = true;
        r2d.collisionDetectionMode = CollisionDetectionMode2D.Continuous;
        r2d.gravityScale = gravityScale;
        facingRight = t.localScale.x > 0;

        if (mainCamera)
        {
            cameraPos = mainCamera.transform.position;
        }
    }

    // Update is called once per frame
    void Update()
    {
        // Movement controls
        if ((Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.D)) && (isGrounded || Mathf.Abs(r2d.velocity.x) > 0.01f))
        {
            moveDirection = Input.GetKey(KeyCode.A) ? -1 : 1;
        }
        else
        {
            if (isGrounded || r2d.velocity.magnitude < 0.01f)
            {
                moveDirection = 0;
            }
        }

        // Change facing direction
        if (moveDirection != 0)
        {
            if (moveDirection > 0 && !facingRight)
            {
                facingRight = true;
                t.localScale = new Vector3(Mathf.Abs(t.localScale.x), t.localScale.y, transform.localScale.z);
            }
            if (moveDirection < 0 && facingRight)
            {
                facingRight = false;
                t.localScale = new Vector3(-Mathf.Abs(t.localScale.x), t.localScale.y, t.localScale.z);
            }
        }

        // Jumping
        if (Input.GetKeyDown(KeyCode.W))
        {
            if (isGrounded || jumpsRemaining > 0)
            {
                r2d.velocity = new Vector2(r2d.velocity.x, jumpHeight);

                // Reset jumps when grounded
                if (isGrounded)
                {
                    jumpsRemaining = maxJumps;
                }
                jumpsRemaining--;
            }
        }

        // Camera follow
        if (mainCamera)
        {
            mainCamera.transform.position = new Vector3(t.position.x, cameraPos.y, cameraPos.z);
        }
    }

    void FixedUpdate()
    {
        Bounds colliderBounds = mainCollider.bounds;
        float colliderRadius = mainCollider.size.x * 0.4f * Mathf.Abs(transform.localScale.x);
        Vector3 groundCheckPos = colliderBounds.min + new Vector3(colliderBounds.size.x * 0.5f, colliderRadius * 0.9f, 0);
        // Check if player is grounded
        Collider2D[] colliders = Physics2D.OverlapCircleAll(groundCheckPos, colliderRadius);
        //Check if any of the overlapping colliders are not player collider, if so, set isGrounded to true
        isGrounded = false;
        if (colliders.Length > 0)
        {
            for (int i = 0; i < colliders.Length; i++)
            {
                if (colliders[i] != mainCollider)
                {
                    isGrounded = true;
                    break;
                }
            }
        }

        // Apply movement velocity
        r2d.velocity = new Vector2((moveDirection) * maxSpeed, r2d.velocity.y);

        // Simple debug
        Debug.DrawLine(groundCheckPos, groundCheckPos - new Vector3(0, colliderRadius, 0), isGrounded ? Color.green : Color.red);
        Debug.DrawLine(groundCheckPos, groundCheckPos - new Vector3(colliderRadius, 0, 0), isGrounded ? Color.green : Color.red);
    }
}

ステップ 3: ゲームをテストする

Unity でゲームを 実行し、ダブル ジャンプ機能をテストします。キャラクターは地面から離れた後、空中で 2 回ジャンプできる必要があります。

おすすめの記事
Unity 用プレーヤー 3D および 2D ウォール ジャンプ チュートリアル
Unity用2Dキャラクターコントローラー
キャラクター コントローラー Unity でリジッドボディをプッシュする機能を追加する方法
Unity の FPS プレーヤーにしゃがみを追加する
Unity モバイル タッチ コントロールの作り方
Unity のキャラクター コントローラーに移動プラットフォームのサポートを追加する方法
Unity の宇宙船コントローラー