Menu
CoddyTech

Empurrando objetos

Parte da seção Criando Jogos de Verdade do Journey de Unity da Coddy. Lição 41 de 60.

Um CharacterController nunca empurra nada: faça-o andar contra uma caixa com um Rigidbody e ele para como se estivesse diante de uma parede. Em vez disso, o Unity chama OnControllerColliderHit(ControllerColliderHit hit) nos próprios scripts do controlador para cada collider tocado por um Move, incluindo o chão, e o script decide o que acontece. hit.collider é o que foi tocado, hit.moveDirection é a direção do Move que o tocou, e hit.normal é a direção para a qual a superfície está voltada no ponto de contato. Este é o próprio script de empurrão do Unity:

public float pushPower = 2f;

void OnControllerColliderHit(ControllerColliderHit hit)
{
    Rigidbody body = hit.collider.attachedRigidbody;
    if (body == null || body.isKinematic) return;   // nada para empurrar
    if (hit.moveDirection.y < -0.3f) return;        // está sob nossos pés

    Vector3 pushDir = new Vector3(hit.moveDirection.x, 0f, hit.moveDirection.z);
    body.linearVelocity = pushDir * pushPower;
}

Cada return tem um motivo. O chão e as paredes não têm Rigidbody, então body é null para eles, e eles são tocados em quase todo Move. Um corpo cinemático só se move quando o próprio script o move, então uma velocidade não faz nada com ele. Um Move direcionado acentuadamente para baixo tocou algo sob os pés, e a caixa sobre a qual o jogador está em pé não deve ser empurrada.

A direção do empurrão mantém apenas x e z, então uma caixa desliza pelo chão em vez de ser pressionada contra ele. Definir linearVelocity, em vez de adicionar uma força, faz uma caixa leve e uma pesada se moverem no mesmo ritmo; body.AddForce(pushDir * pushPower, ForceMode.Impulse) empurraria menos a caixa pesada.

challenge icon

Desafio

Médio

Faça o jogador chutar as bolas em que esbarrar ao andar.

  1. Em Kicker.cs, escreva void OnControllerColliderHit(ControllerColliderHit hit) e obtenha Rigidbody body = hit.collider.attachedRigidbody;.
  2. Use return quando body for null ou cinemático, ou quando hit.moveDirection.y < -0.3f (uma bola sob os pés).
  3. Defina body.linearVelocity como a direção do movimento com y igual a 0, multiplicada por kickPower, mais Vector3.up * lift.

Pressione “Jogar” e caminhe em direção à bola vermelha: ela voa para a frente e para cima. Depois, pressione “Verificar”.

Experimente você mesmo

using UnityEngine;

public class Kicker : MonoBehaviour
{
    public float kickPower = 6f;
    public float lift = 4f;

    // Chute as bolas com as quais o jogador esbarrar
}

Todas as lições de Criando Jogos de Verdade

Pratique por conta própria: Playground de Unity