Dinge schieben
Teil des Abschnitts Echte Spiele entwickeln der Unity-Journey von Coddy. Lektion 41 von 60.
Ein CharacterController schiebt niemals etwas: Läufst du damit gegen eine Kiste mit einem Rigidbody, hält er an, als wäre dort eine Wand. Stattdessen ruft Unity für jeden Collider, den ein Move berührt, einschließlich des Bodens, OnControllerColliderHit(ControllerColliderHit hit) in den eigenen Skripten des Controllers auf, und das Skript entscheidet, was passiert. hit.collider ist das berührte Objekt, 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. Boden und 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. Bei einem Move, der steil nach unten zeigt, wurde etwas unter den Füßen berührt, und die Kiste, auf der der Spieler steht, sollte nicht weggeschoben werden.
Die Schieberichtung behält nur x und z bei, sodass eine Kiste über den Boden gleitet, anstatt in ihn hineingedrückt zu werden. Wenn du linearVelocity festlegst, statt eine Kraft hinzuzufügen, bewegen sich eine leichte und eine schwere Kiste gleich schnell; body.AddForce(pushDir * pushPower, ForceMode.Impulse) würde die schwere Kiste weniger stark schieben.
Aufgabe
MittelLass den Spieler die Bälle wegkicken, gegen die er läuft.
- Schreibe in
Kicker.csvoid OnControllerColliderHit(ControllerColliderHit hit)und hole dirRigidbody body = hit.collider.attachedRigidbody;. - Führe
returnaus, wennbodynull oder kinematisch ist oder wennhit.moveDirection.y < -0.3f(ein Ball unter den Füßen). - Setze
body.linearVelocityauf die Laufrichtung mit y 0, multipliziert mitkickPower, plusVector3.up * lift.
Drücke „Spielen“ und lauf gegen den roten Ball: Er fliegt nach vorne und oben. Drücke dann „Prüfen“.
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
}
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