Menu
CoddyTech

Yerde Durmak

Coddy'nin Unity Journey'sinin Fizik ve Oynanış bölümünün bir parçası. Ders 11 / 71.

Her temasın bir normali vardır: uzunluğu 1 olan, dokunduğun yüzeye dik ve yüzeyden nesnene doğru yönelen bir doğrultu. collision.GetContact(0) ilk temas noktasıdır ve normal hangi tarafa dokunduğunu gösterir. Düz zeminde dururken bu değer (0, 1, 0); sağındaki duvara temas ettiğinde (-1, 0, 0); tavana başını çarptığında ise (0, -1, 0) olur.

Bu sandık, yere inişleri yandan çarpmalardan ayırt eder:

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

Testte tam olarak 1 yerine normal.y > 0.5f kullanılır; böylece eğimler de zemin sayılır: 60 derecelik bir eğimde y değeri 0.5'tir ve bu, herhangi birinin yürüyebileceğinden daha dik bir eğimdir. Uzun süren durumlar için iki mesaj daha yardımcı olur: temas sürdüğü müddetçe her fizik adımında OnCollisionStay çalışır; temas sona erdiğinde ise bir kez OnCollisionExit çalışır. Artık hiçbir şey temas etmediğinden, çıkışta temas noktası bulunmaz; bu nedenle orada GetContact çağırma.

challenge icon

Görev

Kolay

Oyuncunun yalnızca bir şeyin üzerinde dururken zıplamasını sağla.

  1. private bool grounded; ekle. OnCollisionStay içinde collision.GetContact(0).normal.y > 0.5f olduğunda değerini true yap; OnCollisionExit içinde ise false yap.
  2. FixedUpdate() içinde yalnızca if (jumpPressed && grounded) koşulu sağlandığında zıpla ve havadayken yapılan bir basışın yok sayılması için bu if ifadesinden sonra jumpPressed = false; ayarla.

“Oyna” düğmesine bas ve çift zıplamayı dene: ikinci basış hiçbir şey yapmaz. Ardından “Kontrol et” düğmesine bas.

Kendin dene

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

Fizik ve Oynanış bölümündeki tüm dersler

Kendi başına pratik yap: Unity playground