Auf dem Boden stehen
Teil des Abschnitts Physik und Gameplay der Unity-Journey von Coddy. Lektion 11 von 71.
Jeder Kontakt hat eine Normale: eine Richtung der Länge 1, die senkrecht zur berührten Oberfläche steht und von ihr weg zu deinem Objekt zeigt. collision.GetContact(0) ist der erste Kontaktpunkt, und seine normal sagt dir, welche Seite du berührt hast. Auf ebenem Boden ist sie (0, 1, 0); an einer Wand zu deiner Rechten ist sie (-1, 0, 0); wenn du mit dem Kopf gegen eine Decke stößt, ist sie (0, -1, 0).
Diese Kiste unterscheidet Landungen von seitlichen Stößen:
void OnCollisionEnter(Collision collision)
{
Vector3 normal = collision.GetContact(0).normal;
if (normal.y > 0.5f)
{
Debug.Log("Landed on " + collision.gameObject.name);
}
else
{
Debug.Log("Bumped the side of " + collision.gameObject.name);
}
}Der Test lautet normal.y > 0.5f statt genau 1, damit auch Hänge als Boden gelten: Bei einer Steigung von 60 Grad beträgt y 0.5 – steiler, als jemand hinaufgehen würde. Zwei weitere Meldungen helfen bei allem, was länger andauert: OnCollisionStay wird bei jedem Physikschritt ausgeführt, solange der Kontakt besteht, und OnCollisionExit einmal, wenn er endet. Beim Verlassen gibt es keine Kontaktpunkte, da sich nichts mehr berührt. Rufe dort also nicht GetContact auf.
Aufgabe
EinfachLass den Spieler nur springen, wenn er auf etwas steht.
- Füge
private bool grounded;hinzu. Setze es inOnCollisionStayauf true, wenncollision.GetContact(0).normal.y > 0.5f; setze es inOnCollisionExitauf false. - Lass ihn in
FixedUpdate()nur springen, wennif (jumpPressed && grounded)gilt, und setzejumpPressed = false;danach, also nach diesemif, damit ein Tastendruck in der Luft verworfen wird.
Drücke „Spielen“ und versuche einen Doppelsprung: Der zweite Tastendruck bewirkt nichts. Drücke dann „Prüfen“.
Probier es selbst
using UnityEngine;
public class Hopper : MonoBehaviour
{
public float speed = 4f;
public float jump = 6f;
private Rigidbody rb;
private bool jumpPressed;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
jumpPressed = true;
}
}
void FixedUpdate()
{
float h = Input.GetAxisRaw("Horizontal");
rb.linearVelocity = new Vector3(h * speed, rb.linearVelocity.y, 0);
if (jumpPressed)
{
rb.AddForce(Vector3.up * jump, ForceMode.Impulse);
jumpPressed = false;
}
}
}
Alle Lektionen in Physik und Gameplay
1Rigidbody
Schwerkraft und MasseMit AddForce schiebenMit einem Impuls springenFixedUpdate für PhysikGeschwindigkeitKinematische KörperRückblick: Startrampe4Coroutinen
AufrufenWiederholt aufrufen, Aufruf abbrechenDeine erste CoroutineSchleifen in CoroutinenCoroutinen beendenRückblick: Countdown10Projekt: Arena-Flucht
Die ArenaJäger2Kollisionen
OnCollisionEnterWas habe ich getroffen?Beim Aufprall zerbrechenAuf dem Boden stehenAbprallen und ReibungCollider-FormenRückblick: Zerstörbare Wand5Projekt: Münzrausch
Der rollende BallMünzen zum Einsammeln11Abschließende Herausforderungen
KanonenreichweiteBewegliche ZieleMurmelgolfIns LochEscape RoomDie TürÜbe selbstständig: Unity-Playground