Dinge schieben
Teil des Abschnitts Echte Spiele entwickeln der Unity-Journey von Coddy. Lektion 40 von 56.
Ein CharacterController schiebt nichts: Bewegt man ihn gegen eine Kiste mit einem Rigidbody, bleibt er stehen, als wäre dort eine Wand. Stattdessen ruft Unity für jeden Collider, den ein Move berührt, auch für den Boden, OnControllerColliderHit(ControllerColliderHit hit) in den eigenen Skripten des Controllers auf, und das Skript entscheidet, was passiert. hit.collider ist das, was berührt wurde, hit.moveDirection die Richtung des Move, der es berührt hat, und hit.normal die Richtung, in die die Oberfläche am Kontaktpunkt zeigt. Dies ist Unitys eigenes Schiebeskript:
public float pushPower = 2f;
void OnControllerColliderHit(ControllerColliderHit hit)
{
Rigidbody body = hit.collider.attachedRigidbody;
if (body == null || body.isKinematic) return; // nichts zum Schieben
if (hit.moveDirection.y < -0.3f) return; // es befindet sich unter unseren Füßen
Vector3 pushDir = new Vector3(hit.moveDirection.x, 0f, hit.moveDirection.z);
body.linearVelocity = pushDir * pushPower;
}Jedes return hat einen Grund. Der Boden und die Wände haben keinen Rigidbody, daher ist body für sie null, und sie werden bei fast jedem Move berührt. Ein kinematischer Körper bewegt sich nur, wenn sein eigenes Skript ihn bewegt, daher bewirkt eine Geschwindigkeit bei ihm nichts. Ein Move, der steil nach unten zeigt, hat etwas unter den Füßen berührt, und die Kiste, auf der der Spieler steht, sollte nicht weggeschoben werden.
Die Schubrichtung behält nur x und z bei, sodass eine Kiste über den Boden gleitet, statt in ihn hineingedrückt zu werden. Wird linearVelocity gesetzt, statt eine Kraft hinzuzufügen, bewegen sich eine leichte und eine schwere Kiste mit derselben Geschwindigkeit; body.AddForce(pushDir * pushPower, ForceMode.Impulse) würde die schwere weniger stark schieben.
Aufgabe
MittelTritt die Bälle über den Hof. Der Player läuft mit einem CharacterController (Walker.cs, fertig). Schreibe Kicker.cs, ebenfalls auf dem Player. Im Inspector werden kickPower (6) und lift (4) festgelegt.
- Wenn der Player gegen einen Körper läuft, der geschoben werden kann, setze dessen
linearVelocityauf die Laufrichtung, flach entlang des Bodens, multipliziert mitkickPower, plusliftgerade nach oben, sodass der Ball nach vorne und oben fliegt. - Der Boden und der Pfosten haben keinen Rigidbody: Überspringe sie ohne Fehler.
- Ein Ball unter den Füßen des Players wird nicht getreten.
Drücke Play und tritt gegen den roten Ball, dann Check.
Probier es selbst
using UnityEngine;
public class Kicker : MonoBehaviour
{
public float kickPower = 6f;
public float lift = 4f;
// Schieße die Bälle weg, gegen die der Spieler läuft
}
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
1Text auf dem Bildschirm
Canvas und TextPunktestand anzeigenZahlen formatierenEin Countdown-TimerRückblick: Tachometer4Szenen und Level
Eine Szene ladenDas Level neu startenNächstes LevelZwischen Szenen beibehaltenRückblick: Levelauswahl10Projekt: 3D-Plattformer
Der ParcoursBewegliche Plattformen2Buttons 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