Schwerkraft von Hand
Teil des Abschnitts Echte Spiele entwickeln der Unity-Journey von Coddy. Lektion 39 von 60.
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. Deshalb speichert das Skript die vertikale Geschwindigkeit in einem Feld, addiert in jedem Frame gravity * Time.deltaTime dazu und bewegt sich damit in derselben Move wie beim Laufen:
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 freien Fall aus dem Stillstand beträgt die Geschwindigkeit des Controllers nach einer halben Sekunde -4.9 Einheiten pro Sekunde und nach einer Sekunde -9.81.
Das Zurücksetzen ist genauso wichtig wie der Fall. Auf dem Boden hält Move den Controller an, aber nichts hält das Feld an: Ohne Zurücksetzen wächst es weiter, während der Spieler steht, und beim nächsten Schritt über eine 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 sein als Min Move Distance; dann tut Move nichts und isGrounded wird false. isGrounded wird vor Move ausgelesen, beschreibt also den Move des letzten Frames.
Aufgabe
MittelGib dem Taucher Schwerkraft, damit sein Fall immer schneller wird.
- Setze am Anfang von
Update(), wenncontroller.isGroundedgilt undverticalSpeed < 0fist,verticalSpeed = -1f;. - Addiere
gravity * Time.deltaTimedazu und begrenze den Wert mitMathf.Maxauf-maxFalloder höher. - Setze vor der Zeile
controller.Movemove.y = verticalSpeed;.
Drücke „Spielen“ und gehe vom Turm: Der Fall beschleunigt sich auf 10 Einheiten pro Sekunde. Drücke dann „Prüfen“.
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 addieren, 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);
}
}
Alle Lektionen in Echte Spiele entwickeln
1Text auf dem Bildschirm
Canvas und TextPunktestand anzeigenZahlen formatierenEin Countdown-TimerRückblick: Tachometer2Buttons und Bildschirme
Buttons und onClickLambdasVerknüpfungen im InspectorPanels ein- und ausblendenGesundheitsbalkenRückblick: Upgrade-Shop5Speichern mit PlayerPrefs
Eine Zahl speichernMit einem Standardwert ladenHöchstpunktzahlEinstellungen speichernRückblick: Münzen auf der Bank8Charaktersteuerung
CharacterController.MoveSchwerkraft von HandSpringenDinge schiebenDorthin bewegen, wohin du schaustRückblick: DoppelsprungÜbe selbstständig: Unity-Playground