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에서 게임을 실행하고 이중 점프 기능을 테스트하세요. 캐릭터는 땅을 떠난 후 공중에서 두 번 점프할 수 있어야 합니다.

추천 기사
Unity용 플레이어 3D 및 2D 벽 점프 튜토리얼
Unity의 캐릭터 컨트롤러에 움직이는 플랫폼 지원을 추가하는 방법
Unity용 2D 캐릭터 컨트롤러
캐릭터 컨트롤러 Unity에서 강체를 푸시하는 기능을 추가하는 방법
Unity용 하향식 플레이어 컨트롤러 튜토리얼
Unity에서 파쿠르 시스템 구현
Unity용 대화 시스템