Menu
CoddyTech

Asla Düz Değil

Coddy'nin Unity Oyunu: Tuğla Kırma kursunda ders 10 / 19.

Bir tuğlanın köşesinden seken top neredeyse yatay ilerleyebilir ve oyuncu beklerken sahayı tekrar tekrar geçebilir. Çözüm, hız düzeltmesinde: yönün y bileşeni çok küçükse, onu bir minimum değere ayarla ve yeniden normalize et.

Mathf.Abs, bir sayının işaretini yok sayarak büyüklüğünü verir; bu nedenle tek bir test, yukarı ve aşağı giden topları yakalar. Mathf.Sign, negatif bir sayı için -1, diğer durumlarda 1 verir; böylece aşağı giden top aşağı gitmeye devam eder.

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

Minimum değer 0.4 olduğunda, (0.99, -0.12, 0) yönünün y bileşeni -0.4 olur ve normalize edildiğinde yaklaşık (0.93, -0.37, 0) elde edilir: hâlâ sağa ve aşağıya, ama artık geri dönecek kadar dik. Daha dik yönlere dokunulmaz.

challenge icon

Görev

Orta

Topun sahayı neredeyse yatay şekilde geçmesini önle.

  1. Ball içinde public float minVertical = 0.3f; ekle.
  2. FixedUpdate içinde Vector3 direction = rb.linearVelocity.normalized; satırını al. Mathf.Abs(direction.y) < minVertical koşulu sağlanıyorsa direction.y = Mathf.Sign(direction.y) * minVertical; olarak ayarla ve tekrar normalize et.
  3. rb.linearVelocity = direction * speed; olarak ayarla.

“Oyna” düğmesine bas: top uzun süre yatay şekilde sahayı geçmez. Ardından “Kontrol et” düğmesine bas.

Kendin dene

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

Unity Oyunu: Tuğla Kırma bölümündeki tüm dersler

Kendi başına pratik yap: Unity playground