Unıty Raycast Nedir?

Sosyal medyada paylaşın

Bu yazıda sizlere Raycast hakkında bilgi vermeye çalışacağım.

Raycast’i küçükken oynadığımız lazerler gibi düşünebilirsiniz. İki nokta arasında görünmeyen bir lazer oluşturmak için Raycast kullanırız. Fakat isterseniz daha sonradan Debug.DrawRay kullanarak çizgi çizdirebilirsiniz. Ufak bir bilgi olsun, CS:GO oyununda silahlar ateşlenince karşıdaki düşmana gidip gitmediğini veya gittiyse hangi bölgesine çarptığını belirlemek için raycast kullanılır. Raycast’i Swerve mekaniğinde de kullanabiliriz. Kullanım alanı baya fazla kısacası 🙂

Peki nerelerde Raycast kullanılır? Pek çok kullanım alanı bulunuyor;

  • Silah ile ateş etme
  • Merminin çarptığı konumda decal oluşturma
  • VR’da objeler ile etkileşim
  • Uzaktaki bir nesnenin özelliklerine erişme

 Raycast(Vector3 origin, Vector3 direction, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers) şeklinde tanımlanır. Hadi kodlamaya geçelim.

    void FixedUpdate()
    {
        Vector3 direction = transform.TransformDirection(Vector3.forward);

        if (Physics.Raycast(transform.position, direction, 100))    
            print("There is something in front of the object!");          
        else
            print("There is not something in front of the object!");

        Debug.DrawRay(transform.position, direction*100, Color.red);
    }

Öncelikle ray’in hangi yöne doğru hareket edeceğini direction vektörüyle belirliyoruz. Burada TransformDirection kullanarak başlangıç noktasının local transform’undan forward’a bir vektör elde ettik. TransformDirection kullanmasaydım başlangıç noktasının local transform’unu dikkate almayacaktı, örneğin başlangıc noktasının rotasyonunu değiştirsem bile yine merkez noktasından forward’a alacaktı.

Physics sınıfını kullanarak Raycast fonksiyonu oluşturuyorum. Sırayla başlangıç pozisyonunu, gideceği doğrultuyu ve maximum kaç birim uzaklığı algılayabilsin onu belirliyorum. İf içine girerse bu koşullarda bir objeye ray’in çarptığı anlaşılır. Else bloğunda ise herhangi bir objeye çarmadığı anlaşılır. Çarpışma olmamasının nedeni mesafe yetersizliği veya o mesafedeki objenin collideri olmamasından kaynaklanabilir. Raycast’in hit detect edebilmesi için objelerin collider’a sahip olması gerekir.

Gelelim layer mantığına, layer objeleri sınıflandırmamıza yardımcı olur. Örneğin bir carpışmada çarpılan objenin tag’ını nasıl kontrol ettiriyorsam aynı şekilde layer’ini de kontrol ettirip işime devam edebilirim. Layer, tag gibi objeleri sınıflandırmamıza yardımcı olur, bundan başka bir kullanım alanı daha var ona başka bir yazıda devam edelim.

  if (Physics.Raycast(transform.position, direction, 100, 1 << 8))
-------------------------------------------------------------

  LayerMask layer = LayerMask.GetMask("xxx");
  if (Physics.Raycast(transform.position, direction, 100, layer))

Layer’i Raycast’ın 4. parametresinde veririm. İster yukarıdaki gibi ister alttaki gibi layer verebilirim. Artık sadece belirlediğim Layer’e sahip olan objelerde raycast’ım çalışacak. Örneğin bir objenin Layer’i “Env” olsun, benim ray’im o objeye çarpsa dahi layer kontrolünden geçemediği için çalışmayacak.

    LayerMask layer = LayerMask.GetMask("xxx");
    void FixedUpdate()
    {
        RaycastHit hitInfo;
        Vector3 direction = transform.TransformDirection(Vector3.forward);

        if (Physics.Raycast(transform.position, direction, out hitInfo, 100, layer))
            print(hit.transform.name);
        else
            print("There is not something in front of the object!");
    }

Gelelim hit parametresine, true döndürülürse, hitInfo yakın çarpıştırıcının çarptığı obje hakkındaki bilgilere erişmemize yardımcı olacaktır. Yukarda bulunan örnekteki gibi hit.transform.name diyip ray’in çarptığı objenin ismine ulaşabilirim. Veya çarpılan objenin herhangi bir componentine erişebilirim.

    void FixedUpdate()
    {
        RaycastHit hit;

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out hit, 10000))
            print(hit.transform.name);       
    }

Eğer ekrandan dokunduğumuz doğrultudaki objeler ile iletişime geçmek istersek yukarıdaki kod gibi ray’i tanımlarız ve ekranda dokunduğumuz pozisyonun üç boyutlu dünyadaki izdüşümüne hareketini sağlarız. Son olarak ufak bir bilgi daha vermek istiyorum, Raycast kodlarını FixedUpdate’de çalıştırırsanız Update’e göre daha net ve doğru sonuçlar verecektir.

Umarım yardımcı olabilmişimdir, iyi çalışmalar…