Menu
CoddyTech

No chão

Parte da seção Física e Jogabilidade do Journey de Unity da Coddy. Lição 11 de 71.

Cada contato tem uma normal: uma direção de comprimento 1, perpendicular à superfície que você tocou, apontando para fora dela, em direção ao seu objeto. collision.GetContact(0) é o primeiro ponto de contato, e sua normal informa qual lado você tocou. Em pé em um chão plano, ela é (0, 1, 0); contra uma parede à sua direita, é (-1, 0, 0); ao bater a cabeça no teto, é (0, -1, 0).

Esta caixa distingue aterrissagens de batidas laterais:

void OnCollisionEnter(Collision collision)
{
    Vector3 normal = collision.GetContact(0).normal;
    if (normal.y > 0.5f)
    {
        Debug.Log("Landed on " + collision.gameObject.name);
    }
    else
    {
        Debug.Log("Bumped the side of " + collision.gameObject.name);
    }
}

O teste é normal.y > 0.5f, em vez de exatamente 1, para que as inclinações também contem como chão: y é 0.5 em uma inclinação de 60 graus, mais íngreme do que qualquer pessoa consegue subir andando. Mais duas mensagens ajudam com qualquer coisa que dure: OnCollisionStay é executado a cada passo da física enquanto o contato durar, e OnCollisionExit uma vez quando ele termina. Uma saída não tem pontos de contato, já que nada mais está se tocando, então não chame GetContact nesse caso.

challenge icon

Desafio

Fácil

Faça o jogador pular somente quando estiver em cima de alguma coisa.

  1. Adicione private bool grounded;. Em OnCollisionStay, defina como verdadeiro quando collision.GetContact(0).normal.y > 0.5f; em OnCollisionExit, defina como falso.
  2. Em FixedUpdate(), pule somente if (jumpPressed && grounded) e defina jumpPressed = false; depois desse if, para que um pressionamento no ar seja descartado.

Pressione “Jogar” e tente dar um pulo duplo: o segundo pressionamento não faz nada. Depois, pressione “Verificar”.

Experimente você mesmo

using UnityEngine;

public class Hopper : MonoBehaviour
{
    public float speed = 4f;
    public float jump = 6f;
    private Rigidbody rb;
    private bool jumpPressed;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            jumpPressed = true;
        }
    }

    void FixedUpdate()
    {
        float h = Input.GetAxisRaw("Horizontal");
        rb.linearVelocity = new Vector3(h * speed, rb.linearVelocity.y, 0);
        if (jumpPressed)
        {
            rb.AddForce(Vector3.up * jump, ForceMode.Impulse);
            jumpPressed = false;
        }
    }
}

Todas as lições de Física e Jogabilidade

Pratique por conta própria: Playground de Unity