Thêm hỗ trợ nhảy đôi vào bộ điều khiển nhân vật nền tảng 2D trong Unity

Trong hướng dẫn này, chúng tôi sẽ nâng cao trình phát nền tảng 2D trong Unity bằng cách kết hợp tính năng nhảy kép.

Hướng dẫn sửa đổi này giả định rằng bạn đã làm theo hướng dẫn sau: 2D Character Controller for Unity.

Bước 1: Khai báo biến

Thêm các biến sau vào tập lệnh hiện có để quản lý tính năng nhảy kép:

public int maxJumps = 2;
int jumpsRemaining;

Các biến này sẽ theo dõi số lần nhảy tối đa được phép 'maxJumps' và số lần nhảy còn lại 'jumpsRemaining'.

Bước 2: Sửa đổi logic nhảy

Điều chỉnh logic nhảy trong phương thức 'void Update()' để triển khai tính năng nhảy kép:

// 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--;
    }
}

Việc sửa đổi này cho phép người chơi thực hiện một cú nhảy nếu được tiếp đất hoặc vẫn còn những cú nhảy.

Kiểm tra tập lệnh sửa đổi cuối cùng bên dưới:

'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);
    }
}

Bước 3: Kiểm tra trò chơi của bạn

Chạy trò chơi của bạn trong Unity và kiểm tra tính năng nhảy kép. Nhân vật có thể nhảy hai lần giữa không trung sau khi rời khỏi mặt đất.

Bài viết được đề xuất
Cách thêm hỗ trợ nền tảng di chuyển vào bộ điều khiển nhân vật trong Unity
Bộ điều khiển nhân vật 2D cho Unity
Thêm hiệu ứng lắc đầu vào máy ảnh trong Unity
Hướng dẫn nhảy tường 3D và 2D của người chơi cho Unity
Bộ điều khiển nhân vật Cách thêm khả năng đẩy các vật cứng trong Unity
Triển khai hệ thống Parkour trong Unity
Thêm Cúi người vào Trình phát FPS trong Unity