Menu
CoddyTech

Stanie na podłożu

Część sekcji Fizyka i rozgrywka ścieżki Unity w Coddy. Lekcja 11 z 71.

Każdy kontakt ma normalną: wektor o długości 1, prostopadły do powierzchni, której dotykasz, skierowany od niej w stronę twojego obiektu. collision.GetContact(0) to pierwszy punkt kontaktu, a jego normal informuje cię, której strony dotykasz. Stojąc na płaskim podłożu, ma wartość (0, 1, 0); przy ścianie po prawej stronie ma wartość (-1, 0, 0); uderzając głową w sufit, ma wartość (0, -1, 0).

Ta skrzynia odróżnia lądowanie od uderzenia w bok:

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);
    }
}

Test sprawdza normal.y > 0.5f, a nie dokładnie 1, dzięki czemu za podłoże uznawane są również pochyłości: wartość y wynosi 0.5 na pochyłości o kącie 60 stopni, czyli bardziej stromej niż te, po których ktokolwiek chodzi. Dwa kolejne komunikaty pomagają obsłużyć wszystko, co trwa dłużej: OnCollisionStay uruchamia się przy każdym kroku fizyki, gdy kontakt trwa, a OnCollisionExit — raz, gdy kontakt się kończy. Przy zakończeniu kontaktu nie ma punktów kontaktu, ponieważ niczego już nie dotykasz, więc nie wywołuj wtedy GetContact.

challenge icon

Wyzwanie

Łatwy

Pozwól graczowi skakać tylko wtedy, gdy stoi na czymś.

  1. Dodaj private bool grounded;. W OnCollisionStay ustaw wartość na true, gdy collision.GetContact(0).normal.y > 0.5f; w OnCollisionExit ustaw ją na false.
  2. W FixedUpdate() wykonuj skok tylko przy if (jumpPressed && grounded), a po tym if ustaw jumpPressed = false;, aby naciśnięcie w powietrzu zostało zignorowane.

Naciśnij „Graj” i spróbuj wykonać podwójny skok: drugie naciśnięcie nic nie robi. Następnie naciśnij „Sprawdź”.

Spróbuj swoich sił

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;
        }
    }
}

Wszystkie lekcje w sekcji Fizyka i rozgrywka

Poćwicz samodzielnie: Edytor online Unity