Menu
CoddyTech

Celuj paletką

Lekcja 4 z 16 w kursie Gra w Unity: Zbijanie klocków w Coddy.

Przy idealnym odbiciu gracz nie może celować: piłka opuszcza paletkę pod takim samym kątem, pod jakim do niej doleciała. W grach typu Brick Breaker to paletka decyduje o kierunku. Trafienie blisko lewego końca wysyła piłkę w górę i w lewo, trafienie w środek — prosto w górę, a im dalej od środka, tym szerszy kąt.

Zamień miejsce trafienia na liczbę od -1 na lewym końcu do 1 na prawym końcu: poziome przesunięcie piłki względem środka paletki podziel przez połowę szerokości paletki. Załóżmy, że paletka ma 4 jednostki szerokości, a jej środek znajduje się w x = 2, zaś piłka trafia w x = 3. Przesunięcie wynosi 1, połowa szerokości wynosi 2, więc otrzymujemy liczbę 0.5, a nowy kierunek to 0.5 w poziomie i 1 w górę, czyli (0.5, 1, 0), po normalizacji. Trafienie dokładnie w koniec daje 1 lub -1, co odpowiada kątowi 45 stopni od kierunku prosto w górę. Ogranicz tę liczbę do tego zakresu, ponieważ piłka może dotknąć rogu paletki nieco poza jej końcem.

Funkcja OnCollisionEnter piłki jest wywoływana po obliczeniu odbicia przez fizykę, więc ustawiona w niej prędkość zastępuje poprzednią. Ściany wysyłają tę samą wiadomość i powinny zachować zwykłe odbicie, więc najpierw sprawdź, co zostało trafione. collision.collider.bounds to prostopadłościan zajmowany przez collider w świecie, z uwzględnieniem skali:

void OnCollisionEnter(Collision collision)
{
    Bounds box = collision.collider.bounds;
    Debug.Log(collision.gameObject.name + " is " + box.size.x + " wide, centered at x = " + box.center.x);
}
challenge icon

Wyzwanie

Łatwy

Dodaj OnCollisionEnter(Collision collision) do Ball:

  1. Nie rób nic, chyba że trafiony obiekt ma tag Paddle.
  2. Oblicz x: od współrzędnej x piłki odejmij współrzędną x paletki, a następnie podziel wynik przez połowę szerokości paletki (collision.collider.bounds.size.x); ogranicz wartość do przedziału od -1 do 1.
  3. Ustaw prędkość Rigidbody na new Vector3(x, 1f, 0f), znormalizuj ją i pomnóż przez speed.

Naciśnij Play, odbij piłkę przy obu końcach paletki, a następnie kliknij Check.

Spróbuj swoich sił

using UnityEngine;
using UnityEngine.InputSystem;

public class Ball : MonoBehaviour
{
    public Transform paddle;
    public float speed = 9f;

    Rigidbody rb;
    bool launched;

    void Awake()
    {
        rb = GetComponent<Rigidbody>();
        PhysicsMaterial bouncy = new PhysicsMaterial("Bouncy");
        bouncy.bounciness = 1f;
        bouncy.dynamicFriction = 0f;
        bouncy.staticFriction = 0f;
        bouncy.bounceCombine = PhysicsMaterialCombine.Maximum;
        bouncy.frictionCombine = PhysicsMaterialCombine.Minimum;
        GetComponent<Collider>().material = bouncy;
    }

    void Update()
    {
        if (launched) return;
        transform.position = paddle.position + Vector3.up * 0.5f;
        if (Keyboard.current.spaceKey.wasPressedThisFrame) Launch(new Vector3(0.3f, 1f, 0f));
    }

    public void Launch(Vector3 direction)
    {
        launched = true;
        rb.linearVelocity = direction.normalized * speed;
    }

    void FixedUpdate()
    {
        if (!launched) return;
        rb.linearVelocity = rb.linearVelocity.normalized * speed;
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Gra w Unity: Zbijanie klocków