Controler de caractere 2D pentru Unity

2D Platformer este un tip de joc în care jucătorul sare între platforme, evită obstacolele și luptă cu inamicii, toate acestea fiind observate dintr-o perspectivă laterală 2D.

Sharp Coder Video player

Pentru a crea un controler de caractere 2D Platformer în Unity, urmați pașii de mai jos.

Controlerul va fi bazat pe fizică și va folosi o componentă Rigidbody2D.

Pași

  • Deschide Scena cu nivelul tău 2D (asigură-te că sprite-urile de nivel au atașate colidere 2D, astfel încât jucătorul să nu cadă)
  • Creați un nou GameObject și apelați-l "Player"
  • Creați un alt GameObject, numiți-l "player_sprite" și adăugați-i componenta Sprite Renderer
  • Atribuiți sprite-ul la "player_sprite" și mutați-l în interiorul obiectului "Player"

  • Creați un nou script, numiți-l "CharacterController2D" și inserați codul de mai jos în interiorul acestuia:

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;

    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) && isGrounded)
        {
            r2d.velocity = new Vector2(r2d.velocity.x, jumpHeight);
        }

        // 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);
    }
}
  • Atașați scriptul CharacterController2D la obiectul "Player" (veți observa că a adăugat și alte componente numite Rigidbody2D și CapsuleCollider2D)
  • Modificați dimensiunile CapsuleCollider2D până când se potrivesc cu jucătorul Sprite
  • Asigurați-vă că nu există colisionare copii și că CapsuleCollider2D este singurul colisionator atașat acestui jucător

În scriptul CharacterController2D există o opțiune de a atribui variabilei Camerei principale care poate fi orice Cameră care va urmări jucătorul:

Controlerul de caractere 2D este acum gata!

Articole sugerate
Player 3D și 2D Wall Jump Tutorial pentru Unity
Adăugarea suportului pentru salt dublu la un controler de caractere 2D platformer în Unity
Controler de caractere Cum să adăugați capacitatea de a împinge corpuri rigide în Unity
Controler de avion pentru Unity
Controler de jucător planetar bazat pe corp rigid pentru Unity
Tutorial de sus în jos pentru controlerul jucătorului pentru Unity
Controler de jucător RTS și MOBA pentru Unity