Unity'de 2D Platformer Karakter Denetleyicisine Double Jump Desteği Ekleme

Bu eğitimde, çift atlama özelliği ekleyerek Unity'teki 2D platform oynatıcısını geliştireceğiz.

Bu değişiklik kılavuzu, şu öğreticiyi zaten takip ettiğinizi varsaymaktadır: 2D Karakter Denetleyicisi için Unity.

Adım 1: Değişkenleri Bildirin

Çift atlama özelliğini yönetmek için aşağıdaki değişkenleri mevcut betiğe ekleyin:

public int maxJumps = 2;
int jumpsRemaining;

Bu değişkenler izin verilen maksimum atlama sayısını 'maxJumps' ve kalan atlamaları 'jumpsRemaining' takip edecektir.

Adım 2: Atlama Mantığını Değiştirin

Çift atlama özelliğini uygulamak için 'void Update()' yöntemindeki atlama mantığını ayarlayın:

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

Bu değişiklik, oyuncunun topraklanmışsa veya hala atlamaları kalmışsa bir atlama gerçekleştirmesine olanak tanır.

Aşağıdaki son değiştirilen komut dosyasını kontrol edin:

'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. Adım: Oyununuzu Test Edin

Unity'de oyununuzu çalıştırın ve çift atlama özelliğini test edin. Karakter yerden kalktıktan sonra havada iki kez zıplayabilmelidir.

Önerilen Makaleler
Unity'de Karakter Kontrolörüne Hareketli Platform Desteği Nasıl Eklenir?
Unity için 2D Karakter Kontrol Cihazı
Karakter Denetleyicisi Birlik İçinde Sert Cisimleri İtme Yeteneği Nasıl Eklenir
Unity için Yukarıdan Aşağıya Oyuncu Kontrol Eğiticisi
Unity'de Parkur Sisteminin Uygulanması
Unity'de FPS Player'a Çömelme Ekleme
Unity için Oyuncu 3D ve 2D Duvardan Atlama Eğitimi