Menu
CoddyTech

Gravedad manual

Parte de la sección Creación de juegos reales del Journey de Unity de Coddy. Lección 38 de 56.

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. Por eso, el script guarda la velocidad vertical en un campo, le suma gravity * Time.deltaTime en cada fotograma y se mueve según ella en el mismo Move que el desplazamiento 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, 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 cumplir dos funciones: gravity * Time.deltaTime es la velocidad ganada 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 al siguiente; una variable local volvería a empezar en 0 en cada fotograma. Al caer desde el reposo, el controlador alcanza -4.9 unidades por segundo después de medio segundo y -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á quieto, y al dar el siguiente paso fuera de un saliente cae a toda velocidad. Se reinicia a un número negativo pequeño en lugar de a 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 inferior a 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

El buceador está de pie en una torre alta, y las flechas lo mueven (ya está escrito). Añádele gravedad en Diver.cs. El Inspector establece gravity (-12) y maxFall (10), y el script tiene el campo verticalSpeed.

  • Cada fotograma, verticalSpeed aumenta en gravity por segundo, y el buceador se mueve hacia abajo con ese valor en el mismo Move que el movimiento al caminar.
  • El aire ralentiza una caída larga: el buceador nunca cae más rápido que maxFall unidades por segundo.
  • Cuando el controlador está en el suelo y verticalSpeed es menor que 0, establece verticalSpeed en -1.

Pulsa Play, sal de la torre caminando y después pulsa Check.

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 estar en el suelo, añade la gravedad, limita la caída y guarda el resultado en move.y

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

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