Hinzufügen von Double Jump-Unterstützung zu einem 2D-Platformer-Charakter-Controller in Unity

In diesem Tutorial werden wir den 2D-Plattformspieler in Unity durch die Integration einer Doppelsprungfunktion verbessern.

In dieser Änderungsanleitung wird davon ausgegangen, dass Sie das folgende Tutorial bereits befolgt haben: 2D Character Controller für Unity.

Schritt 1: Variablen deklarieren

Fügen Sie dem vorhandenen Skript die folgenden Variablen hinzu, um die Doppelsprungfunktion zu verwalten:

public int maxJumps = 2;
int jumpsRemaining;

Diese Variablen verfolgen die maximal zulässige Anzahl von Sprüngen 'maxJumps' und die verbleibenden Sprünge 'jumpsRemaining'.

Schritt 2: Sprunglogik ändern

Passen Sie die Sprunglogik in der Methode 'void Update()' an, um die Doppelsprungfunktion zu implementieren:

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

Diese Modifikation ermöglicht es dem Spieler, einen Sprung durchzuführen, wenn er am Boden liegt oder noch Sprünge übrig hat.

Sehen Sie sich das endgültige geänderte Skript unten an:

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

Schritt 3: Testen Sie Ihr Spiel

Führen Sie Ihr Spiel in Unity aus und testen Sie die Doppelsprungfunktion. Der Charakter sollte in der Lage sein, zweimal in die Luft zu springen, nachdem er den Boden verlassen hat.