Criando o Personagem e Configurando os Controles 🎮🕹️

Agora vamos adicionar nosso personagem ao jogo e configurar seus controles para que ele possa se movimentar corretamente no cenário.

Passos para Criar o Personagem:

1️⃣ Importar o Personagem

  • Vá até a pasta:
    Pixel Adventure 1 > Assets > Main Characters > Virtual Guy
  • Escolha o primeiro frame da animação Idle e arraste-o para a Scene View.
  • Isso criará um novo GameObject com um Sprite Renderer.

2️⃣ Renomear o Objeto

  • Na Hierarchy, renomeie o objeto para Player.

3️⃣ Adicionar Componentes Essenciais

  • No Inspector, clique em Add Component e adicione:
    • Rigidbody 2D (para física do personagem)
      • Defina Gravity Scale para 2 (para um salto mais realista).
    • Capsule Collider 2D (para colisões)
      • Ajuste o tamanho para cobrir todo o personagem.

Configurando os Controles do Jogador

Agora, vamos criar um script para a movimentação:

1️⃣ Criar o Script de Movimento

  • Na pasta Assets, crie uma nova pasta chamada Scripts.
  • Dentro dela, clique com o botão direito e selecione Create > C# Script.
  • Nomeie o script como PlayerController e abra-o no Visual Studio.

2️⃣ Adicionar Código para Movimentação

Abra o script e substitua o código por:

using UnityEngine; // Importa a biblioteca UnityEngine, necessária para usar os componentes da Unity.

public class PlayerController : MonoBehaviour // Declara a classe PlayerController que herda de MonoBehaviour.
{
    public float moveSpeed = 5f; // Velocidade de movimento do personagem.
    public float jumpForce = 10f; // Força do pulo do personagem.
    private Rigidbody2D rb; // Componente Rigidbody2D que controlará a física do personagem.
    private bool isGrounded; // Variável booleana para verificar se o personagem está no chão.

    void Start()
    {
        rb = GetComponent<Rigidbody2D>(); // Obtém o componente Rigidbody2D anexado ao jogador.
    }

    void Update()
    {
        float move = Input.GetAxis("Horizontal"); // Obtém a entrada do jogador nos eixos horizontais (teclas A/D ou setas).
        rb.linearVelocity = new Vector2(move * moveSpeed, rb.linearVelocity.y); // Define a velocidade do personagem no eixo X, mantendo a velocidade no eixo Y.

        // Faz o personagem girar 180 graus no eixo Y quando se mover.
        if (move != 0) // Se houver movimento (valor diferente de 0).
        {
            transform.localScale = new Vector3(Mathf.Sign(move), 1, 1); // Inverte o personagem na direção do movimento, alterando o eixo X da escala.
        }

        if (Input.GetButtonDown("Jump") && isGrounded) // Verifica se a tecla de pulo foi pressionada e se o personagem está no chão.
        {
            rb.linearVelocity = new Vector2(rb.linearVelocity.x, jumpForce); // Aplica uma força no eixo Y para fazer o personagem pular.
        }
    }

    void OnCollisionEnter2D(Collision2D collision) // Método chamado quando o personagem colide com outro objeto.
    {
        if (collision.gameObject.CompareTag("Ground")) // Verifica se o objeto colidido tem a tag "Ground".
        {
            isGrounded = true; // Define isGrounded como verdadeiro, permitindo o pulo.
        }
    }

    void OnCollisionExit2D(Collision2D collision) // Método chamado quando o personagem sai da colisão com um objeto.
    {
        if (collision.gameObject.CompareTag("Ground")) // Verifica se o objeto colidido tem a tag "Ground".
        {
            isGrounded = false; // Define isGrounded como falso, impedindo um novo pulo até tocar o chão novamente.
        }
    }
}

3️⃣ Aplicar o Script ao Personagem

  • Arraste o script PlayerController para o Player na Hierarchy.

Passos para Configurar o Chão:

1️⃣ Selecionar os Tiles do Chão

  • Na Hierarchy, encontre os objetos que representam o chão do jogo.
  • Se o chão foi criado usando Tilemap, selecione o Tilemap correspondente.

2️⃣ Adicionar a Tag “Ground”

  • No Inspector, clique no campo Tag (localizado no topo).
  • Se a tag “Ground” ainda não existir, clique em Add Tag….
  • Clique no botão + e crie uma nova tag chamada Ground.
  • Volte para o objeto do chão e selecione a Tag “Ground”.

3️⃣ Testar a Configuração

  • Pressione Play na Unity.
  • O personagem agora só poderá pular quando estiver tocando o chão!

Com isso, garantimos que o sistema de pulo funcione corretamente, evitando que o personagem pule infinitamente no ar. 🚀

1️⃣ Criando as Animações

  1. Abra a pasta de sprites
    • Vá até a pasta: Pixel Adventure 1 > Assets > Main Characters > Virtual Guy.
  2. Criar a animação Idle (parado)
    • Selecione todos os sprites da animação Idle.
    • Arraste para a Hierarchy.
    • Salve como Idle.anim.
  3. Criar a animação Run (correndo)
    • Selecione todos os sprites da animação Run.
    • Arraste para a Hierarchy.
    • Salve como Run.anim.
  4. Criar a animação Jump (pulando)
    • Selecione o sprite único de pulo Jump.png.
    • Arraste para a Hierarchy.
    • Salve como Jump.anim.

2️⃣ Criando e Configurando o Animator

  1. Criar o Animator Controller
    • Vá para a pasta Assets e clique com o botão direito.
    • Escolha Create > Animator Controller.
    • Nomeie como PlayerAnimator.
  2. Adicionar ao Personagem
    • Selecione o personagem na Hierarchy.
    • No Inspector, clique em Add Component e escolha Animator.
    • Arraste o PlayerAnimator para o campo Controller.
  3. Criar Estados e Transições
    • duplo clique no PlayerAnimator para abrir o Animator.
    • Arraste as animações Idle, Run e Jump para dentro do Animator.
    • Defina Idle como estado Padrão (Set as Layer Default State).

3️⃣ Criando os Parâmetros

  1. No Animator, clique em Parameters.
  2. Adicione os seguintes parâmetros:
    • Float → Speed (Para alternar entre Idle e Run).
    • Bool → IsJumping (Para alternar para Jump).

4️⃣ Alterando Animações via Código

Agora, no script do personagem, precisamos mudar as animações de acordo com o movimento.

📌 Abra o PlayerController.cs e adicione:

using UnityEngine; // Importa a biblioteca UnityEngine para usar os componentes da Unity.

public class PlayerController : MonoBehaviour // Declara a classe PlayerController, que controla o personagem.
{
    public float moveSpeed = 5f; // Define a velocidade de movimento do personagem.
    public float jumpForce = 10f; // Define a força do pulo do personagem.
    private Rigidbody2D rb; // Variável para armazenar o componente Rigidbody2D do personagem.
    private Animator anim; // Variável para armazenar o componente Animator do personagem.
    private bool isGrounded; // Variável booleana para verificar se o personagem está tocando o chão.

    void Start() // Método chamado quando o jogo inicia.
    {
        rb = GetComponent<Rigidbody2D>(); // Obtém o componente Rigidbody2D do personagem.
        anim = GetComponent<Animator>(); // Obtém o componente Animator do personagem.
    }

    void Update() // Método chamado a cada frame do jogo.
    {
        float move = Input.GetAxis("Horizontal"); // Obtém a entrada do jogador no eixo horizontal (A/D ou setas).
        rb.velocity = new Vector2(move * moveSpeed, rb.velocity.y); // Define a velocidade do personagem no eixo X, mantendo a velocidade no eixo Y.

        // Define a animação de corrida com base no movimento.
        anim.SetFloat("Speed", Mathf.Abs(move)); // Passa o valor absoluto da velocidade para o Animator.

        // Faz o personagem girar na direção correta.
        if (move != 0) // Se houver movimento (valor diferente de 0).
        {
            transform.localScale = new Vector3(Mathf.Sign(move), 1, 1); // Inverte o personagem na direção do movimento.
        }

        // Verifica se o jogador pressionou a tecla de pulo e se está no chão.
        if (Input.GetButtonDown("Jump") && isGrounded)
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpForce); // Aplica uma força no eixo Y para fazer o personagem pular.
            anim.SetBool("IsJumping", true); // Ativa a animação de pulo.
        }
    }

    void OnCollisionEnter2D(Collision2D collision) // Método chamado quando o personagem colide com outro objeto.
    {
        if (collision.gameObject.CompareTag("Ground")) // Verifica se o objeto colidido tem a tag "Ground".
        {
            isGrounded = true; // Define que o personagem está no chão.
            anim.SetBool("IsJumping", false); // Desativa a animação de pulo.
        }
    }

    void OnCollisionExit2D(Collision2D collision) // Método chamado quando o personagem sai da colisão com um objeto.
    {
        if (collision.gameObject.CompareTag("Ground")) // Verifica se o objeto do qual o personagem saiu tem a tag "Ground".
        {
            isGrounded = false; // Define que o personagem não está mais no chão.
        }
    }
}

5️⃣ Testando o Jogo!

✔️ Idle quando o personagem estiver parado.
✔️ Run quando ele estiver se movendo.
✔️ Jump quando ele estiver no ar.

Agora o personagem está animado e pronto para ação! 🚀🔥

🚀 Resolvendo Problemas de Escala do Personagem na Unity 2D

Se você está criando um jogo de plataforma na Unity e percebeu que o tamanho do personagem está errado ou resetando quando dá Play, isso pode ser um problema de escala.

🛠 O Problema:

🔹 Seu personagem está muito pequeno na cena.
🔹 Você ajusta a escala no Inspector, mas ao dar Play, ela volta para 1.
🔹 O personagem pode girar errado ao mudar de direção.

✅ A Solução:

Use este código atualizado para garantir que o personagem sempre mantenha a escala correta e gire corretamente ao se movimentar:

using UnityEngine; // Importa a biblioteca UnityEngine para usar os componentes da Unity.

public class PlayerController : MonoBehaviour // Declara a classe PlayerController, que controla o personagem.
{
    public float moveSpeed = 5f; // Define a velocidade de movimento do personagem.
    public float jumpForce = 10f; // Define a força do pulo do personagem.
    private Rigidbody2D rb; // Variável para armazenar o componente Rigidbody2D do personagem.
    private Animator anim; // Variável para armazenar o componente Animator do personagem.
    private bool isGrounded; // Variável booleana para verificar se o personagem está tocando o chão.

    private Vector3 defaultScale = new Vector3(8, 8, 1); // Define a escala fixa do personagem.

    void Start() // Método chamado quando o jogo inicia.
    {
        rb = GetComponent<Rigidbody2D>(); // Obtém o componente Rigidbody2D do personagem.
        anim = GetComponent<Animator>(); // Obtém o componente Animator do personagem.

        transform.localScale = defaultScale; // Garante que a escala inicial seja sempre 8x8.
    }

    void Update() // Método chamado a cada frame do jogo.
    {
        float move = Input.GetAxis("Horizontal"); // Obtém a entrada do jogador no eixo horizontal (A/D ou setas).
        rb.velocity = new Vector2(move * moveSpeed, rb.velocity.y); // Define a velocidade do personagem no eixo X, mantendo a velocidade no eixo Y.

        // Verifica se o personagem está correndo.
        if (move != 0 && isGrounded) // Se o personagem estiver se movendo e no chão.
        {
            anim.SetBool("Run", true); // Ativa a animação de corrida.
            anim.SetBool("Idle", false); // Desativa a animação de Idle.
            anim.SetBool("Jump", false); // Desativa a animação de pulo.
        }
        else if (move == 0 && isGrounded) // Se o personagem estiver parado no chão.
        {
            anim.SetBool("Idle", true); // Ativa a animação de Idle.
            anim.SetBool("Run", false); // Desativa a animação de corrida.
            anim.SetBool("Jump", false); // Desativa a animação de pulo.
        }

        // Faz o personagem girar na direção correta SEM ALTERAR A ESCALA
        if (move > 0) // Se estiver se movendo para a direita.
        {
            transform.localScale = new Vector3(defaultScale.x, defaultScale.y, defaultScale.z); // Mantém a escala original.
        }
        else if (move < 0) // Se estiver se movendo para a esquerda.
        {
            transform.localScale = new Vector3(-defaultScale.x, defaultScale.y, defaultScale.z); // Inverte a escala no eixo X para virar o personagem.
        }

        // Verifica se o jogador pressionou a tecla de pulo e se está no chão.
        if (Input.GetButtonDown("Jump") && isGrounded)
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpForce); // Aplica uma força no eixo Y para fazer o personagem pular.
            anim.SetBool("Jump", true); // Ativa a animação de pulo.
            anim.SetBool("Idle", false); // Desativa a animação de Idle.
            anim.SetBool("Run", false); // Desativa a animação de corrida.
            isGrounded = false; // Define que o personagem não está mais no chão.
        }
    }

    void OnCollisionEnter2D(Collision2D collision) // Método chamado quando o personagem colide com outro objeto.
    {
        if (collision.gameObject.CompareTag("Ground")) // Verifica se o objeto colidido tem a tag "Ground".
        {
            isGrounded = true; // Define que o personagem está no chão.
            anim.SetBool("Jump", false); // Desativa a animação de pulo.

            // Ajusta corretamente para Idle ou Run ao tocar o chão.
            if (rb.velocity.x != 0) 
            {
                anim.SetBool("Run", true); // Ativa a animação de corrida se estiver se movendo.
                anim.SetBool("Idle", false); // Desativa a animação de Idle.
            }
            else
            {
                anim.SetBool("Idle", true); // Ativa a animação de Idle se estiver parado.
                anim.SetBool("Run", false); // Desativa a animação de corrida.
            }
        }
    }

    void OnCollisionExit2D(Collision2D collision) // Método chamado quando o personagem sai da colisão com um objeto.
    {
        if (collision.gameObject.CompareTag("Ground")) // Verifica se o objeto do qual o personagem saiu tem a tag "Ground".
        {
            isGrounded = false; // Define que o personagem não está mais no chão.
        }
    }
}

🔹 O que esse código faz?

Mantém a escala fixa mesmo depois de dar Play.
Impede que a Unity resete a escala automaticamente.
Garante que o personagem gire corretamente sem bagunçar o tamanho.

Se o seu personagem estava com problemas de escala, agora está resolvido! 🚀

Caso ainda tenha dúvidas, assista ao tutorial no YouTube: (colocar link aqui).

🚀 Capítulo 3: Criando o Próximo Passo do Jogo!

Agora que o personagem está funcionando corretamente, com controles e animações, vamos dar continuidade ao desenvolvimento do nosso jogo de plataforma 2D!

🔹 O que vamos fazer no próximo capítulo?

Neste capítulo, vamos:

  • Adicionar inimigos à cena.
  • Criar um sistema de coleta de itens (como moedas ou power-ups).
  • Trabalhar na pontuação e HUD para mostrar os pontos e a vida do jogador.

Tudo isso ajudará a tornar o jogo mais desafiador e interessante para quem jogar!

🔹 Como sempre, se você tiver dúvidas, assista ao vídeo tutorial no YouTube:

(Colocar link aqui)