Menu
CoddyTech

Jangan Pernah Datar

Pelajaran 10 dari 16 dalam kursus Game Unity: Brick Breaker di Coddy.

Bola bisa bergerak hampir menyamping: pantulan dari sudut balok atau dorongan dari bola lain dapat membuatnya bergerak hampir mendatar, melintasi arena berulang kali tanpa turun. Permainan pun terhenti sementara pemain menunggu bola turun. Perbaikannya ada pada perbaikan kecepatan: setelah membuat arah sepanjang 1 unit, jika komponen y terlalu kecil, tetapkan y ke nilai minimum lalu normalkan kembali.

Dua method Mathf melakukan tugas ini. Mathf.Abs memberikan besar suatu angka tanpa tandanya, sehingga satu pemeriksaan dapat mendeteksi bola yang bergerak naik maupun turun. Mathf.Sign memberikan -1 untuk angka negatif dan 1 untuk angka lainnya, sehingga y yang baru mempertahankan arah bola: bola yang bergerak turun tetap bergerak turun.

float drift = -0.12f;
Debug.Log(Mathf.Abs(drift));    // 0.12
Debug.Log(Mathf.Sign(drift));   // -1

Telusuri langkahnya dengan nilai minimum 0.3 dan arah (0.99, -0.12, 0). Besar y, yaitu 0.12, kurang dari 0.3, sehingga y menjadi -0.3, dan (0.99, -0.3, 0) yang dinormalkan menjadi kira-kira (0.96, -0.29, 0): bola tetap bergerak ke kanan dan ke bawah, kini cukup curam untuk kembali. Normalisasi membuat y sedikit lebih kecil dari nilai minimum lagi, lalu langkah berikutnya menambahnya, sehingga nilainya tetap sedikit di bawah 0.3. Arah yang lebih curam tidak berubah.

challenge icon

Tantangan

Sedang
  1. Tambahkan public float minVertical = 0.3f ke Ball.
  2. Di FixedUpdate(), ambil arah dari velocity, lalu normalkan. Jika nilai absolut y-nya kurang dari minVertical, atur y ke minVertical dengan tanda yang sama seperti y, lalu normalkan kembali arahnya.
  3. Kemudian, seperti sebelumnya, atur velocity ke arah tersebut dikalikan speed.

Tekan Play, lalu Check.

Coba sendiri

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

    public void ResetToPaddle()
    {
        launched = false;
        rb.linearVelocity = Vector3.zero;
    }

    void FixedUpdate()
    {
        if (!launched) return;
        rb.linearVelocity = rb.linearVelocity.normalized * speed;
    }

    void OnCollisionEnter(Collision collision)
    {
        if (!collision.gameObject.CompareTag("Paddle")) return;
        float offset = transform.position.x - collision.transform.position.x;
        float halfWidth = collision.collider.bounds.size.x / 2f;
        float x = Mathf.Clamp(offset / halfWidth, -1f, 1f);
        rb.linearVelocity = new Vector3(x, 1f, 0f).normalized * speed;
    }

    void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("DeathZone")) GameManager.Instance.BallLost(this);
    }
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Game Unity: Brick Breaker