Menu
CoddyTech

Schwerkraft von Hand

Teil des Abschnitts Echte Spiele entwickeln der Unity-Journey von Coddy. Lektion 38 von 56.

Ein CharacterController fällt nur, wenn dein Skript ihn fallen lässt, und ein echter Fall wird schneller: Die Schwerkraft erhöht die Fallgeschwindigkeit jede Sekunde um etwa 9.81 Einheiten pro Sekunde. Deshalb speichert das Skript die vertikale Geschwindigkeit in einem Feld, addiert in jedem Frame gravity * Time.deltaTime dazu und bewegt sich damit im selben Move wie beim Gehen:

public float gravity = -9.81f;
float verticalSpeed;

void Update()
{
    if (controller.isGrounded && verticalSpeed < 0f)
    {
        verticalSpeed = -2f;   // am Boden: den Fall beenden, einen leichten Druck nach unten beibehalten
    }
    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 kommt zweimal für zwei Aufgaben vor: gravity * Time.deltaTime ist die in diesem Frame hinzugewonnene Geschwindigkeit, und die Geschwindigkeit multipliziert mit Time.deltaTime ist die in diesem Frame zurückgelegte Strecke. Die Geschwindigkeit ist ein Feld, weil sie von Frame zu Frame erhalten bleiben muss; eine lokale Variable würde in jedem Frame wieder bei 0 beginnen. Beim Fallen aus dem Stillstand hat der Controller nach einer halben Sekunde eine Geschwindigkeit von -4.9 Einheiten pro Sekunde und nach einer Sekunde von -9.81.

Das Zurücksetzen ist genauso wichtig wie das Fallen. Auf dem Boden stoppt Move den Controller, aber nichts stoppt das Feld: Ohne das Zurücksetzen wächst es weiter, während der Spieler steht, und beim nächsten Schritt von einer Kante fällt er mit voller Geschwindigkeit. Es wird auf eine kleine negative Zahl statt auf 0 zurückgesetzt, damit jeder Move weiterhin gegen den Boden drückt: Bei einer hohen Bildrate kann der Schub durch die Schwerkraft eines einzelnen Frames kürzer als Min Move Distance sein, Move bewirkt nichts und isGrounded wird false. isGrounded wird vor dem Move ausgelesen, beschreibt also den Move des letzten Frames.

challenge icon

Aufgabe

Mittel

Der Taucher steht auf einem hohen Turm, und die Pfeile bewegen ihn (bereits geschrieben). Füge in Diver.cs Schwerkraft hinzu. Im Inspector werden gravity (-12) und maxFall (10) festgelegt, und das Skript hat das Feld verticalSpeed.

  • In jedem Frame erhöht sich verticalSpeed pro Sekunde um gravity, und der Taucher bewegt sich im selben Move wie beim Gehen um diesen Wert nach unten.
  • Luft bremst einen langen Fall: Der Taucher fällt nie schneller als maxFall Einheiten pro Sekunde.
  • Wenn der Controller am Boden ist und verticalSpeed kleiner als 0 ist, setze verticalSpeed auf -1.

Drücke Play, gehe vom Turm herunter und klicke dann auf Check.

Probier es selbst

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()
    {
        // Schwerkraft: verticalSpeed am Boden zurücksetzen, Schwerkraft hinzufügen, die Fallgeschwindigkeit begrenzen und den Wert in move.y speichern

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

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Echte Spiele entwickeln