Menu
CoddyTech

Empujar objetos

Parte de la sección Creación de juegos reales del Journey de Unity de Coddy. Lección 41 de 60.

Un CharacterController nunca empuja nada: si lo haces caminar contra una caja con un Rigidbody, se detiene como si chocara contra una pared. En su lugar, Unity llama a OnControllerColliderHit(ControllerColliderHit hit) en los propios scripts del controlador por cada collider que toca un Move, incluido el suelo, y el script decide qué ocurre. hit.collider es lo que se tocó, hit.moveDirection es la dirección del Move que lo tocó y hit.normal es la dirección hacia la que apunta su superficie en el punto de contacto. Este es el script de empuje de Unity:

public float pushPower = 2f;

void OnControllerColliderHit(ControllerColliderHit hit)
{
    Rigidbody body = hit.collider.attachedRigidbody;
    if (body == null || body.isKinematic) return;   // no hay nada que empujar
    if (hit.moveDirection.y < -0.3f) return;        // está bajo nuestros pies

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

Cada return tiene un motivo. El suelo y las paredes no tienen Rigidbody, así que body es null para ellos, y se tocan en casi cada Move. Un cuerpo cinemático solo se mueve cuando su propio script lo mueve, así que una velocidad no le hace nada. Un Move que apunta pronunciadamente hacia abajo tocó algo bajo los pies, y no se debería empujar la caja sobre la que está parado el jugador.

La dirección del empuje conserva solo x y z, así que la caja se desliza por el suelo en lugar de ser empujada contra él. Establecer linearVelocity, en vez de añadir una fuerza, mueve una caja ligera y una pesada al mismo ritmo; body.AddForce(pushDir * pushPower, ForceMode.Impulse) empujaría menos la caja pesada.

challenge icon

Desafío

Intermedio

Haz que el jugador patee las pelotas con las que se encuentre al caminar.

  1. En Kicker.cs, escribe void OnControllerColliderHit(ControllerColliderHit hit) y obtén Rigidbody body = hit.collider.attachedRigidbody;.
  2. Usa return cuando body sea null o cinemático, o cuando hit.moveDirection.y < -0.3f (una pelota bajo los pies).
  3. Establece body.linearVelocity en la dirección de avance con y igual a 0, multiplicada por kickPower, más Vector3.up * lift.

Pulsa «Jugar» y camina hacia la pelota roja: sale disparada hacia delante y hacia arriba. Después, pulsa «Comprobar».

Pruébalo tú mismo

using UnityEngine;

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

    // Patea las pelotas con las que choca el jugador
}

Todas las lecciones de Creación de juegos reales

Practica por tu cuenta: Playground de Unity