Asla Düz Olmasın
Coddy'nin Unity Oyunu: Tuğla Kırma kursunda ders 10 / 16.
Bir top neredeyse yanlamasına uçmaya başlayabilir: bir tuğlanın köşesinden sekmesi veya başka bir topun itmesi, topu neredeyse yatay hâle getirip yere düşmeden oyun alanında tekrar tekrar ilerlemesine neden olabilir. Oyuncu topun düşmesini beklerken oyun duraklar. Çözüm, hız düzeltmesindedir: yönü 1 birim uzunluğa getirdikten sonra, y bileşeni çok küçükse y'yi minimum değere ayarlayın ve yeniden normalize edin.
İşi iki Mathf metodu yapar. Mathf.Abs, bir sayının işareti olmadan büyüklüğünü verir; böylece tek bir kontrol hem yukarı giden hem de aşağı giden topları yakalar. Mathf.Sign, negatif bir sayı için -1, diğer durumlarda 1 verir; böylece yeni y, topun yönünü korur: aşağı giden bir top yine aşağı gider.
float drift = -0.12f;
Debug.Log(Mathf.Abs(drift)); // 0.12
Debug.Log(Mathf.Sign(drift)); // -1Minimum değeri 0.3 ve yönü (0.99, -0.12, 0) olarak alıp adımları izleyin. y'nin büyüklüğü olan 0.12, 0.3'ün altındadır; bu nedenle y, -0.3 olur ve normalize edilmiş (0.99, -0.3, 0) yaklaşık olarak (0.96, -0.29, 0) değerini verir: top hâlâ sağa ve aşağı gider, artık geri dönecek kadar dik bir açıyla. Normalizasyon y'yi yeniden minimum değerin biraz altına indirir ve sonraki adımda değeri tekrar yükseltir; bu yüzden 0.3'ün biraz altında kalır. Daha dik yönlere dokunulmaz.
Görev
OrtaBallöğesinepublic float minVertical = 0.3fekle.FixedUpdate()içinde yönü, yani hızı normalize ederek al. Y değerinin mutlak değeriminVerticaldeğerinden küçükse, y'nin işaretini kullanarak y'yiminVerticaldeğerine ayarla ve yönü yeniden normalize et.- Ardından, önceki gibi hızı yön ile
speeddeğerini çarparak ayarla.
Play'e bas, ardından Check'e 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);
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.