Controlador de personagem 2D para Unity

2D Platformer é um tipo de jogo onde o jogador salta entre plataformas, evita obstáculos e luta contra inimigos, tudo isso observado de uma perspectiva lateral 2D.

Sharp Coder Reprodutor de vídeo

Para fazer um controlador de personagem de plataforma 2D em Unity, siga as etapas abaixo.

O controlador será baseado na física e usará um componente Rigidbody2D.

Passos

  • Abra a cena com seu nível 2D (certifique-se de que os sprites de nível tenham colisores 2D anexados, para que o jogador não caia)
  • Crie um novo GameObject e chame-o "Player"
  • Crie outro GameObject, chame-o de "player_sprite" e adicione o componente Sprite Renderer a ele
  • Atribua seu sprite a "player_sprite" e mova-o para dentro do objeto "Player"

  • Crie um novo script, nomeie-o "CharacterController2D" e cole o código abaixo dentro dele:

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);
    }
}
  • Anexe o script CharacterController2D ao objeto "Player" (você notará que ele também adicionou outros componentes chamados Rigidbody2D e CapsuleCollider2D)
  • Ajuste as dimensões do CapsuleCollider2D até que correspondam ao Sprite do jogador
  • Certifique-se de que não haja colisores filhos e que o CapsuleCollider2D seja o único colisor conectado a este player

No script CharacterController2D existe uma opção para atribuir a variável Main Camera que pode ser qualquer Camera que seguirá o jogador:

O controlador de personagem 2D está pronto!

Artigos sugeridos
Tutorial de salto de parede 3D e 2D do jogador para Unity
Adicionando suporte de salto duplo a um controlador de personagem de plataforma 2D no Unity
Sistema de Diálogo para a Unidade
Tutorial de lanterna para Unity
Tutorial do controlador Worm 3D para Unity
Tutorial de controlador de jogador de cima para baixo para Unity
Controlador de jogador RTS e MOBA para Unity