Menu
CoddyTech

Gravedad manual

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

Un CharacterController solo cae si tu script hace que caiga, y una caída real se acelera: la gravedad añade aproximadamente 9.81 unidades por segundo a la velocidad de caída cada segundo. Así que el script guarda la velocidad vertical en un campo, le añade gravity * Time.deltaTime en cada fotograma y se mueve según ella en el mismo Move que al caminar:

public float gravity = -9.81f;
float verticalSpeed;

void Update()
{
    if (controller.isGrounded && verticalSpeed < 0f)
    {
        verticalSpeed = -2f;   // en el suelo: detén la caída y mantén un ligero empuje hacia abajo
    }
    verticalSpeed += gravity * Time.deltaTime;

    Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
    move.y = verticalSpeed;
    controller.Move(move * Time.deltaTime);
}

Time.deltaTime aparece dos veces para dos tareas: gravity * Time.deltaTime es la velocidad que se gana en este fotograma, y la velocidad multiplicada por Time.deltaTime es la distancia recorrida en este fotograma. La velocidad es un campo porque debe conservarse de un fotograma a otro; una variable local volvería a empezar en 0 en cada fotograma. Al caer desde el reposo, el controlador está a -4.9 unidades por segundo después de medio segundo y a -9.81 después de uno.

El reinicio es tan importante como la caída. En el suelo, Move detiene el controlador, pero nada detiene el campo: sin el reinicio, sigue aumentando mientras el jugador está de pie, y al dar el siguiente paso fuera de un borde, cae a toda velocidad. Se reinicia a un número negativo pequeño en lugar de 0 para que cada Move siga presionando contra el suelo: con una frecuencia de fotogramas alta, el empuje de la gravedad de un solo fotograma puede ser menor que Min Move Distance, Move no hace nada y isGrounded pasa a ser false. isGrounded se lee antes de Move, así que describe el Move del fotograma anterior.

challenge icon

Desafío

Intermedio

Dale gravedad al buzo para que su caída se acelere.

  1. Al principio de Update(), cuando controller.isGrounded y verticalSpeed < 0f, establece verticalSpeed = -1f;.
  2. Súmale gravity * Time.deltaTime y mantenlo en -maxFall o por encima usando Mathf.Max.
  3. Antes de la línea controller.Move, establece move.y = verticalSpeed;.

Pulsa «Jugar» y camina fuera de la torre: la caída se acelera hasta 10 unidades por segundo. Después, pulsa «Comprobar».

Pruébalo tú mismo

using UnityEngine;

public class Diver : MonoBehaviour
{
    public float speed = 4f;
    public float gravity = -12f;
    public float maxFall = 10f;

    CharacterController controller;
    float verticalSpeed;

    void Start()
    {
        controller = GetComponent<CharacterController>();
    }

    void Update()
    {
        // Gravedad: restablece verticalSpeed al tocar el suelo, aplica la gravedad, limita la caída y asigna el resultado a move.y

        Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
        controller.Move(move * Time.deltaTime);
    }
}

Todas las lecciones de Creación de juegos reales

Practica por tu cuenta: Playground de Unity