Menu
CoddyTech

Empurrão

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

Um recuo é um impulso para longe de tudo o que atingiu você: um único impulso ao longo da linha entre quem bateu e o objeto atingido. Este para-choque empurra para longe tudo o que colide com ele:

[SerializeField] private float power = 8f;

void OnCollisionEnter(Collision collision)
{
    Vector3 away = collision.transform.position - transform.position;
    away.y = 0f;
    collision.rigidbody.AddForce(away.normalized * power, ForceMode.Impulse);
}

collision.transform.position - transform.position aponta do para-choque para o objeto que bateu nele. O valor de y é definido como 0 para que o impulso permaneça nivelado, e normalized faz com que ele tenha o mesmo tamanho, independentemente da distância entre os dois centros. ForceMode.Impulse é um impulso único: ele altera a velocidade de uma só vez em power dividido pela massa, então uma bola de massa 2 é lançada à metade da velocidade de uma bola de massa 1. O ForceMode.Force padrão foi feito para ser aplicado em cada etapa e produz o efeito de uma etapa, 50 vezes menor.

O impulso só dura enquanto nada sobrescrever a velocidade. Um jogador cujo FixedUpdate define rb.linearVelocity com base nas setas em cada etapa perde esse impulso uma etapa depois; portanto, um script assim precisa deixar a velocidade intacta por um instante após um impacto ou mover o jogador com forças.

challenge icon

Desafio

Médio

Faça o jogador liberar uma onda de choque com a tecla Espaço.

  1. Em Input.GetKeyDown(KeyCode.Space), percorra foreach (Collider hit in Physics.OverlapSphere(transform.position, radius)), ignorando o próprio colisor do jogador.
  2. Para cada hit.TryGetComponent(out Rigidbody body), obtenha away = hit.transform.position - transform.position com away.y = 0f.
  3. Chame body.AddForce(away.normalized * power + Vector3.up * lift, ForceMode.Impulse);.

Pressione “Jogar” e pressione Espaço entre as caixas. Depois, clique em “Verificar”.

Experimente você mesmo

using UnityEngine;

public class Shockwave : MonoBehaviour
{
    [SerializeField] private float radius = 4f;
    [SerializeField] private float power = 6f;
    [SerializeField] private float lift = 2f;

    void Update()
    {
        // ao pressionar Space: empurre todos os Rigidbody dentro de radius para longe do jogador
    }
}

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

Pratique por conta própria: Playground de Unity