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.
Desafío
IntermedioHaz que el jugador patee las pelotas con las que se encuentre al caminar.
- En
Kicker.cs, escribevoid OnControllerColliderHit(ControllerColliderHit hit)y obténRigidbody body = hit.collider.attachedRigidbody;. - Usa
returncuandobodysea null o cinemático, o cuandohit.moveDirection.y < -0.3f(una pelota bajo los pies). - Establece
body.linearVelocityen la dirección de avance con y igual a 0, multiplicada porkickPower, másVector3.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
1Texto en pantalla
Canvas y textoMuestra la puntuaciónDa formato a los númerosUn temporizador de cuenta regresivaRepaso: velocímetro2Botones y pantallas
Botones y onClickLambdasConectar en el InspectorPaneles activados y desactivadosBarras de saludRepaso: tienda de mejoras5Guardar con PlayerPrefs
Guardar un númeroCargar con un valor predeterminadoPuntuación más altaGuardar ajustesRepaso: monedas en el banco8Controlador de personaje
CharacterController.MoveGravedad manualSaltarEmpujar objetosMuévete hacia donde mirasRepaso: doble salto3El gestor del juego
Un solo script ejecuta el juegoEl SingletonEstados del juegoActivar el estadoRepaso: gestor de rondas6Proyecto: Corredor sin fin
Tres carrilesObstáculos por delante9El nuevo sistema de entrada
Dos sistemas de entradaTeclado y ratónPulsado en este fotogramaAcciones de entradaRepaso: cambio de entradaPractica por tu cuenta: Playground de Unity