İki nesne arasındaki herhangi bir etkileşim (bu mesafe sıfır bile olsa) belirli bir mesafede gerçekleşir. Unity üzerinden yaptığınız oyununuzda bir nesnenin diğeriyle etkileşime girmesi için etkileşen nesneden etkileşime girilen nesneye bir vektör çizmek gerekir. Bu işlemi gerçekleştirmek için Unity Raycasting kullanıyoruz.
Unity Raycasting nedir?
Kısaca Raycasting, seçtiğimiz nesnenin ilerleyeceği yolda herhangi bir engel olup olmadığını tespit etmek, eğer böyle bir engel varsa nasıl bir etkileşim yaşanacağını belirtmek için seçili görünmez bir ışını(ray) seçili nesneden belirli bir yöne çekme işlemidir. Sözgelimi, oyununuzdaki karakterin bir nesneyi vurmasını istediğinizi hayal edin. Karakter ateş ettiğinde merminin kat ettiği mesafe ve yarattığı etkiyi Raycasting tarafından hesaplayıp işleme koyarsınız.
Bu işlem hem Unity 2D oyununuz hem de Unity 3D oyununuz için yapılabilmektedir. İki tür oyun için raycastingi iki farklı başlıkta inceleyeceğiz.
Unity 3D Raycast
Unity 3D Raycast temel kodunuz şöyle gözükmeli:
Şimdi kodu beraber inceleyim:
Vector3 origin, ışınınızın başlangıç noktasını tanımlar. Bu nokta, veri tabanında X, Y ve Z boyutlarına karşılık gelen Vector3 olarak depolanıyor. Vector3, Unity 3D oyunlarına özeldir, oyununuz üç boyutlu olduğu için tüm vektörler Vector3’te işlenecektir.
Vector3 direction, ışınımızın yönünü belirler. Işınımıza başlangıç noktamızın boyutundan farklı, içinde seyahat edebileceği bir boyut veren bir Vector3’tür.
float distance, ışınımızın başlangıç noktasından belirlediğimiz yönde bir kayan nokta değeri olarak alması gereken mesafedir.
int LayerMask zorunlu olmasa da faydalı olabilecek bir girdi. Unity 3D oyununuzda, ışınınız bazı belirtilen nesneleri yok sayarken diğerlerine çarpabilir. Int değeri atayarak, nesnenizin ışın boyunca aldığı yolda neye çarptığında tepki vereceğini belirtebilirsiniz.
Mouse pozisyonunuzdan Raycasting yapmak
Işınımızın orjin noktasını tanımlamanın farklı yolları vardır. Fare konumunu başlangıç noktası olarak ayarlamak da ışınınızın nereden geldiğini belirlemenin kolay ve etkili bir yolu olabilir. Bu, özellikle bir Unity 3D oyunu üzerinde çalışıyorsanız size yardımcı olacaktır.
Öncelikle, fare konumunuzu Unity dünyasına aktarabilmeniz gerekir. Fare konumumuz, input sınıfının bir özelliğidir. Farenizi bir orijin noktası olarak atamanız için tek yapmanız gereken şeyse Input.mousePosition‘ı kullanmaktır. Oldukça basit, değil mi?
Karakterinizin ateş etmesini istediğiniz senaryo örneğinden devam edelim. Kameradan/göstergeden bir ışın yaratmak için örnek kodu aşağıya bırakıyorum:
Merak etmeyin,her şeyi açıklayacağım. Kodun içine size yol göstermesi için yorumlar ekledim. Yine de gelin, kodun üzerinden tek tek geçelim.
camera = Camera.main, ana kamera değişkeninizi tanımlar. if (Input.GetButton(“Fire1”)) kısmı, karakterinizin ateş etmesi için “Fire” düğmesine bastığınızda ışınınızı tetikleyen -evet, özellikle yaptım- bir if işlevi tanımlıyor. MoveWithRay(), ışınınızın hareketini temsil eden bir girdi.
Input.mousePosition, üç boyutlu bir evrende çalıştığımız için Vector3 olarak tanımlanacaktır. Yukarıda bahsetmiştim.
Biraz derinlik eklemek için camera.transform.position.z‘yi mousePos.z olarak tanımladım.
Buradaki püf nokta Ray ray= camera.ScreenPointToRay(mousePos)) kodu. ScreenPointToRay sayesinde ışınınızı kolayca oluşturacaksınız. Esasen bu, kamera/mouse imlecinden ışın göndermemizi sağlayan kod.
RaycastHit, ışınımız yolda bir şeyle çarpıştığında nasıl bir etki yaratacağını tanımlar.
if (Physics.Raycast(ray,out hit,100))‘i izleyen if işlevi, ışınımızın 100 mesafesinde (bir örnek olarak 100 koydum) bir şeye çarpıp çarpmadığını kontrol eder.
if koşulu sağlanıyorsa, kod şöyle akmaya devam eder:
Vector3 move = hitpoint; (İsabet noktasını değiştiremediğim için yeni bir değişken tanımladım)
move.y = transformation.position.y; (Işınımızın Y boyutunda seyahat etmesini istemiyorum) move.z = transformation.position.z;(Işınımızın Z boyutunda seyahat etmesini istemiyorum.) transform.position = transform.position = Vector3.MoveTowards(transform.position, move, speed) (nesneyi hareket ettirmek için hareket ve hız değişkenlerini tanımlayın)
Unity 2D Raycast
Unity 2D oyununuz için bir ışın tanımlarken, yazımda bazı nüans farkları da olsa, Unity 3D oyunu için yaptığımıza benzer şeyler yapıyoruz:
Vector2 origin, ışınınızın başlangıç noktasını tanımlar. Bu nokta, X ve Y konumları ile bir Vector2 olarak saklanır. Bu kod Unity 2D oyunlarına özeldir, oyununuzun iki boyutu nedeniyle tüm vektörler Vector2’de işlenecektir.
Vector2 direction , ışınımızın yönünü belirler. Işınımıza, başlangıç noktamızın boyutundan farklı, içinde seyahat edebileceği bir boyut veren Vector2 oluyor.
float distance, ışınımızın başlangıç noktasından belirlediğimiz yönde bir kayan nokta değeri olarak alması gereken mesafedir.
int LayerMask zorunlu olmasa da faydalı olabilecek bir girdi. Unity 2D oyununuzda, ışınınız bazı belirtilen nesneleri yok sayarken diğerlerine çarpabilir. Int değeri atayarak, nesnenizin ışın boyunca aldığı yolda neye çarptığında tepki vereceğini belirtebilirsiniz.
Bu kod 2D ışınınızı manuel olarak yazmak içindi.
Bu komut dosyasında, ışınımı otomatik olarak oluşturdum. Işınınızı her iki şekilde de yazabilirsiniz. Yukarıdaki kodun özelliklerinden bahsedelim:
Create2DRay(), fonksiyonu içe aktarmanıza yarar. private void Create2DRay()RaycastHit2D hit= Physics2D.Raycast(transform.position, transform.right, 100) ışınımızın 100 uzaklık değeri ile sağa gitmesini sağlar(soldan sağa ateş ettiğimi varsayıyorum).if (hit.collider != null) ışınımızın yolda herhangi bir şeyle çarpışıp çarpışmadığını kontrol eder.
Işınımızın çarptığı GameObject’in adını yazdırıyoruz şöyle kodladım: Debug.Log(hit.collider.gameObject.name)
Umarım bu kılavuz, Unity 2D veya Unity 3D oyununuzda raycast yapmanıza yardımcı olur.