4. Pulo do Dinossauro - TanookiVerde/WorkshopUnity GitHub Wiki

O Básico sobre Scripting

  1. Você vai abrir o arquivo JumpByScript.cs e vai se deparar com algo mais ou menos assim:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public Class JumpByScript: MonoBahaviour
{
     void Start()
     {
          //Quando o objeto é carregado
     }
     void Update()
     {
          //Todo frame
     }
}
  1. Considerando que você sabe o básico de programação: essas duas funções Start() e Update() chão executadas pela própria Unity em momentos específicos.
  2. A Start() é chamada quando o objeto é carregado. No início de sua "vida".
  3. Por outro lado, o Update() é chamado todo frame do jogo. Um jogo é renderizado em vários frames. Isso significa que essa função acontece durante a "vida" do objeto.
  4. Então em resumo (bem resumido):
    • Coisas que eu quero que aconteçam uma vez, assim que o objeto surgiu na cena, eu coloco dentro da Start()
    • Coisas que eu quero que aconteçam toda hora (todo frame), eu coloco dentro de Update()
  5. Tendo isso em vista, podemos começar a estruturar o componente.

O pulo

  1. Na Unity, existe a possibilidade de adicionarmos uma força em um objeto com Rigidbody2D. Isso é um bom método para simular o pulo. Quando o jogador clicar na tecla Espaço, o jogo vai aplicar uma força para cima, com uma certa intensidade.
  2. Essa força tem que ser aplicada no Rigidbody2D, então precisamos ter uma forma de comunicação com ele:
public Class JumpByScript: MonoBahaviour
{
     //Uma referência a um component do tipo Rigidbody2D
     private Rigidbody2D rigidbodyComponent;
     void Start()
     {
          //Estou capturando o rigidbody deste Game Object e botando na referência que criei.
          rigidbodyComponent = GetComponent<Rigidbody2D>();
     }
(...)
}
  1. O que eu fiz ai em cima é ter um canal de comunicação, que será a variável rigidbodyComponent, e eu peguei o Rigidbody2D que está neste Game Object e botei "dentro" dela.
  2. Agora toda vez que eu quiser usar alguma função do component Rigidbody2D é só eu usar a variável que eu criei. Que fique claro, aplicar uma força num Rigidbody é uma função.
  3. Agora podemos criar o pulo, mas ele só pode acontecer se o jogador clicar na tecla Espaço.
    private void Update()
    {
        //Se a tecla Espaço for pressionada
        if (Input.GetKeyDown(KeyCode.Space))
            Jump(); //Pule (olhar a função definida abaixo)
    }
    private void Jump()
    {
        //Adiciona uma força na direção (x:0,y:100)
        rigidbodyComponent.AddForce(Vector2.up * 100);
    }
  1. Nesse momento, escolhi uma intensidade de 100 de forma arbitrária. Com tudo o que está aqui escrito, o script já deve funcionar. Salve ele e, na Unity, aperte Play.

Alguns ajustes

  1. Perceba que o personagem pode pular infinitamente, sem precisar ter chegado ao chão de novo.
  2. Outra coisa é que a intensidade do pulo não ficou muito boa, certo?
  3. Vou resolver estes dois problemas com o código abaixo. Vou explicar logo em seguida:
(...)
public class JumpByInput : MonoBehaviour
{
    [SerializeField] 
    private float jumpIntensity; //Variavel que controla a intensidade do Pulo. Pode ser modificada no Inspector
    private bool isCollidingWithGround; //Variavel que controla se o personagem está tocando no chão

    private Rigidbody2D rigidbodyComponent; //Uma referência a um component do tipo Rigidbody2D

    private void Start()
    {
        rigidbodyComponent = GetComponent<Rigidbody2D>(); //Coloca na variável uma referencia ao Rigidbody2D no mesmo Game Object
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space) && isCollidingWithGround)//Se Espaço estiver sendo pressionado e o personagem estiver tocando no chão
            Jump(); //Pule
    }
    private void Jump()
    {
        rigidbodyComponent.AddForce(Vector2.up * jumpIntensity); //Adiciona uma força apontando para cima com intensidade jumpIntensity
    }
    private void OnCollisionEnter2D(Collision2D collision) //Unity chama essa função se o Collider2D do objeto colidir com outro Collider2D
    {
        if (collision.collider.CompareTag("Ground")) //Ve se a tag do objeto que colidiu é "Ground" (ele seria o chão)
            isCollidingWithGround = true; //Se ele entrou em colisão com o chão, coloca essa variável como verdadeira
    }
    private void OnCollisionExit2D(Collision2D collision)
    {
        if (collision.collider.CompareTag("Ground"))//Ve se a tag do objeto que colidiu é "Ground" (ele seria o chão)
            isCollidingWithGround = false;//Se ele saiu de colisão com o chão, coloca essa variável como falsa
    }
}
  1. Para o script acima funcionar precisamos criar uma tag chamada "Ground" e colocar ela no objeto que representa o chão.
  2. Para cria a tag, selecione o objeto chão no Hierarchy e note que embaixo do seu nome no Inspector tem um campo "Tag".
  3. Clique nele e depois em "Add Tag"
  4. Use a interface para criar uma Tag chamada Ground
  5. Volte ao Game Object do chão e agora use o campo Tag para selecionar a que você acabou de criar.
  6. Agora rode o jogo que deve estar funcionando 100%!

Uma pequena revisão

  1. Você acabou de entender algumas coisas fundamentais da Unity:
    • Os métodos Start e Update e outras mensagens da Unity (o OnCollisionExit2D, por exemplo): você pode defini-los nos seus Game Objects e a Unity chama eles no momento certo.
    • Usando funções de outros componentes: a comunicação entre Scripts é o que dita comportamentos complexos.
  2. Entender bem como funcionam estes pontos é um ótimo passo para dominar a game engine.