Menu
CoddyTech

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.

challenge icon

Aufgabe

Einfach

Lass den Spieler nur springen, wenn er auf etwas steht.

  1. Füge private bool grounded; hinzu. Setze es in OnCollisionStay auf true, wenn collision.GetContact(0).normal.y > 0.5f; setze es in OnCollisionExit auf false.
  2. Lass ihn in FixedUpdate() nur springen, wenn if (jumpPressed && grounded) gilt, und setze jumpPressed = false; danach, also nach diesem if, 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

Übe selbstständig: Unity-Playground