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.
Desafio
FácilFaça o jogador pular somente quando estiver em cima de alguma coisa.
- Adicione
private bool grounded;. EmOnCollisionStay, defina como verdadeiro quandocollision.GetContact(0).normal.y > 0.5f; emOnCollisionExit, defina como falso. - Em
FixedUpdate(), pule somenteif (jumpPressed && grounded)e definajumpPressed = false;depois desseif, 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
1Rigidbody
Gravidade e MassaEmpurrar com AddForcePular com um ImpulsoFixedUpdate para FísicaVelocidadeCorpos CinemáticosRevisão: Plataforma de Lançamento4Corrotinas
InvocarInvocar repetidamente, Cancelar invocaçãoSua primeira corrotinaLoops em corrotinasInterrompendo corrotinasRevisão: contagem regressiva10Projeto: Fuga da Arena
A ArenaCaçadores2Colisões
OnCollisionEnterO que eu acertei?Quebre no impactoNo chãoQuique e atritoFormas dos collidersRevisão: Parede destrutível5Projeto: Corrida das Moedas
A Bola RolanteMoedas para ColetarPratique por conta própria: Playground de Unity