Empujar objetos
Parte de la sección Creación de juegos reales del Journey de Unity de Coddy. Lección 40 de 56.
Un CharacterController nunca empuja nada: si lo haces caminar contra una caja con un Rigidbody, se detiene como si hubiera 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 ha tocado, hit.moveDirection es la dirección del Move que lo ha tocado y hit.normal es la dirección hacia la que está orientada 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 en esos casos, y se tocan en casi cada Move. Un cuerpo cinemático solo se mueve cuando su propio script lo mueve, por lo que una velocidad no tiene ningún efecto sobre él. Si la dirección de un Move apunta pronunciadamente hacia abajo, se ha tocado algo bajo los pies, y no se debería empujar la caja sobre la que está el jugador.
La dirección del empuje conserva solo x y z, por lo que la caja se desliza por el suelo en lugar de ser presionada contra él. Asignar linearVelocity, en lugar 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 pesada.
Desafío
IntermedioPatea las pelotas por el patio. El jugador camina con un CharacterController (Walker.cs, listo). Escribe Kicker.cs, también en el jugador. En el Inspector se configuran kickPower (6) y lift (4).
- Cuando el jugador camine hacia un cuerpo que se pueda empujar, establece su
linearVelocityen la dirección de la marcha, horizontal a lo largo del suelo, multiplicada porkickPower, másliftdirectamente hacia arriba, para que la pelota salga volando hacia delante y hacia arriba. - El suelo y el poste no tienen Rigidbody: omítelos sin que se produzca un error.
- Una pelota bajo los pies del jugador no recibe una patada.
Pulsa Play y patea la pelota roja; después, pulsa Check.
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
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
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ímetro4Escenas y niveles
Cargar una escenaReiniciar el nivelSiguiente nivelConservar entre escenasRepaso: selección de nivel10Proyecto: plataformas 3D
El recorridoPlataformas móviles2Botones 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 infinito
Tres carrilesObstáculos por delante9El nuevo sistema de entrada
Dos sistemas de entradaTeclado y ratónPulsado en este fotogramaAcciones de entradaRepaso: cambio de entrada