
Unity’de Raycast Kullanımı
Merhaba, bir önceki yazımızda Unity‘de kamera hareketlerini nasıl kısıtlayabileceğimizi öğrenmiştik.Bu derste ise, bir önceki dersimizde öğrendiğimiz kodlardan yararlanacağız.O yüzden aynı kodları yüzeysel olarak anlatacağım.Daha detaylı bilgi için, bir önceki yazıyı okuyabilirsiniz.Bu dersimizin asıl konusu Raycast kullanımı olduğu için, odak noktasından şaşmamamız gerekiyor.Kısaca Raycast nedir açıklayayım.Unity‘de istediğimiz yönde ve uzunlukta atmış olduğumuz, Game penceresinde görmediğimiz görünmez düz bir çizgi şekilde attığımız ışınlardır.Bu ışınlar sizin projenizde belirttiğiniz koşullara göre bir yerlere çarparsa, çarptığı nesneye farklı dinamikler verdirebilirsiniz.Evet şimdi yeni bir proje oluşturalım ve dersimize başlayalım.
Sahne hazırlıkları.
Öncelikle bu dersimizde kullanacağımız senaryoyu açıklayayım.Bir güvenlik kameramız olacak ve birkaç tane hedef olarak kullanacağımız nesnemiz olacak.Bu güvenlik kamerasından attığımız Raycast ışını ile hedeflerimizi tespit etmeye çalışacağız.Tabi kameramızı fare ile kontrol edeceğiz.Şimdi kullanacağımız nesneleri, sahnemize eklemeye başlayalım.İlk olarak Hierarchy penceresinden bir Plane nesnesi ekleyerek başlıyoruz.Bu nesne bizim zeminimizi oluşturacak.
Daha sonra güvenlik kamerasını konumlandıracağımız direğimiz için bir Cube nesnesi oluşturuyoruz.Sonra güvenlik kameramız için de, bir Cube nesnesi oluşturuyoruz.Daha sonra bu nesnemize yeni bir etiket veriyoruz.İsterseniz bu kamera için anten ve lenste yapabilirsiniz.Ben daha çok benzemesi için ekledim.Şimdi bunları Scene penceresinden istediğimiz şekilde ayarlayalım.
Son olarak da, hedef niyetine kullanacağımız Capsule nesnelerini sahnemize ekliyoruz.Ben üç tane oluşturdum.Siz projenize göre istediğiniz kadar oluşturabilirsiniz.Bu nesnelere material dosyası ekliyoruz.Bunu yapmak için Project penceresinde sağ tıklayarak, Create > Maretial seçimini yapıyoruz.İstediğimiz rengi belirledikten sonra istediğimiz nesnenin üzerine sürükleyip bırakıyoruz.Sahnemizin son hali bu şekildedir.
Editörümüzü açalım ve kodlarımızı yazalım.
Şimdi Project penceresinden yeni bir C# Script dosyası oluşturalım ve bir isim verelim.Bu script dosyamızı sürükleyerek güvenlik kamerası için oluşturduğumuz nesnenin üzerine bırakalım.Daha sonra üzerine tıklayarak editörde açalım.
public Camera Kamera; public GameObject Nesne; public float FareHassasiyeti = 5f; public float KameraninXSiniri = 30f; public float KameraninYSiniri = 30f; public float FareninXEkseni; public float FareninYEkseni; RaycastHit hit; Ray isinGonder;
Evet öncelikle projemizde kullanacağımız tüm değişkenleri tanımlıyoruz.İlk satırda, ana kameramız için bir değişken oluşturuyoruz.İkinci satırda, hareket etmesini istediğimiz nesne için bir GameObject tanımlıyoruz.Üçüncü satırda, faremizin hızını ayarlamak için bir değişken tanımlıyoruz.Dördüncü ve beşinci satırda, kameramızın x ve y eksenlerindeki sınırını belirlemek için değişkenler tanımlıyoruz.
Altıncı ve yedinci satırlarda, faremizin x ve y eksenini kontrol etmek için bir değişkenler tanımlıyoruz.Buraya kadar olan değişkenleri sadece kamera hareketlerini kontrol etmek için yazdık.Şimdi bu yazımızın da konusunu oluşturan, Raycast ışınları için gerekli kodlara gelelim.Sekizinci satırda, atmış olduğumuz bu ışınların çarpışma bilgisini tutan bir değişken tanımlıyoruz.Son satırda ise, kullanmak üzere bir ışın tanımlıyoruz.
Kamera = Camera.main; Nesne = GameObject.FindWithTag ("kamera"); Kamera.transform.parent = GameObject.FindWithTag ("kamera").transform; Kamera.transform.position = GameObject.FindWithTag ("kamera").transform.position; Kamera.transform.rotation = GameObject.FindWithTag ("kamera").transform.rotation; Cursor.lockState = CursorLockMode.Locked;
Şimdi start() fonksiyonumuzun içerisine bu kodları yazalım.İlk satırda, ana kameramızı değişkenimize eşitliyoruz.İkinci satırda, etiketi “kamera” olan nesnemizi değişkenimize ekliyoruz.Üçüncü satırda ana kameramızı, etiketi “kamera” olan nesnemizin çocuğu konuma getiriyoruz.Daha önceki yazılarda ebeveyn-çocuk ilişkisini anlatmıştım.Dileyenler önceki yazıları okuyabilir.
Dördüncü satırda ana kameramızın pozisyon değerlerini, etiketi “kamera” olan nesnemiz ile eşitliyoruz.Yine beşinci satırda ana kameramızın rotasyon değerlerini, etiketi “kamera” olan nesnemiz ile eşitliyoruz.Son satırda ise, faremizi kilitlemek için (bir önceki yazıda bu kodu detaylı olarak açıklamıştım.) bu kodu yazıyoruz.
FareninXEkseni -= Input.GetAxis("Mouse Y") * FareHassasiyeti * Time.deltaTime; FareninYEkseni += Input.GetAxis("Mouse X") * FareHassasiyeti * Time.deltaTime; FareninXEkseni = Mathf.Clamp(FareninXEkseni, -KameraninXSiniri, KameraninYSiniri); FareninYEkseni = Mathf.Clamp(FareninYEkseni, -KameraninXSiniri, KameraninYSiniri); Kamera.transform.localRotation = Quaternion.Euler(FareninXEkseni, FareninYEkseni, 0); Nesne.transform.rotation = Quaternion.Euler(FareninXEkseni, FareninYEkseni, 0);
Şimdi gelelim update() fonksiyonuna yazılacak kodları incelemeye.Yukarıdaki kodların ne olduğunu ve ne işe yaradıklarını bir önceki yazıdan bildiğinizi varsayarak çok kısa geçeceğim.İlk satırda faremizin x ekseni için hesaplama yapıyoruz.İkinci satırda ise farenin y ekseni için hesaplama yapıyoruz.Üçüncü satırda faremizin x ekseni için sınırları belirliyoruz.Dördüncü satırda faremizin y ekseni için sınırları belirliyoruz.Beşinci satırda, ana kameramızın hareketi için gerekli kodları yazıyoruz.
Beşinci satırda ise, ana kamera ile hareket edecek nesnemiz için gerekli kodları yazıyoruz.Burada dikkatinizi çekmem gereken bir yer var.Ana kamera için localRotation fonksiyonunu kullanırken, hareket edecek nesnemiz için rotation fonksiyonunu kullanmayı tercih ettik.Bunun nedeni de, ana kameramız çocuk konumda olduğu içindir.”Nesne” değişkenine tanımlı nesnemiz ise, ebeveyn konumundadır.
isinGonder = Kamera.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast (isinGonder, out hit)) { if (hit.transform.name == "HEDEF_1" || hit.transform.name == "HEDEF_2" || hit.transform.name == "HEDEF_3") { Debug.Log ("Birşey tespit ettim! " + hit.transform.name); Debug.DrawLine (isinGonder.origin, Kamera.transform.forward * 10000, Color.green); } else { Debug.Log ("Burada birşey yok!"); Debug.DrawLine (isinGonder.origin, Kamera.transform.forward * 10000, Color.red); } }
Şimdi kameramızdan ışın atarak nesneleri tespit edecek kodları yazmaya geldik.İlk satırda “isinGonder ” değişkenimize, ana kameramızın ortasından geçecek bir ışın tanımlıyoruz.Bunu yaparken ScreenPointToRay fonksiyonundan yaralanıyoruz.Bu kod ekranımızın ortasına bir ışın gönderiyor.Bunu yaparkende faremizin pozisyon değerlerini baz alıyor.İkinci satırda bu ışınımızın çarpışma bilgisini almak için bir koşul oluşturuyoruz.Bu Raycast parantez içerisinde farklı parametreler alabiliyor.
Bu proje için iki parametreye ihtiyacımız var.İlki atmış olduğumuz ışının doğrultusu, ikinciside çarpışma için oluşturduğumuz Raycast.Koşulun içerisine bakacak olursak, yeni bir koşul yazdığımızı görüyoruz.Bu koşul ile, istediğimiz nesnelerin üzerine kamera ile geldiğimiz zaman ne yapacağımızı belirliyoruz.Ben sadece bulduğumuz nesnenin adını, Console penceresine yazdır ve ışının rengini yeşil yap dedim.Eğer bulamazsa da, ışınımızın rengini kırmızıya çeviriyor.Yazının başında, Raycast ışınlarının gözle görülmediğini söylemiştim.
İşte bu ışınları Scene penceresinde görmek için, Debug.DrawLine fonksiyonundan yararlanıyoruz. Parametrelerine bakacak olursak, ilk önce ışınımızın başlangıcını alıyoruz.Daha sonra ışının gideceği yönünü ve ışınımızın ne kadar uzun olacağını belirliyoruz.Son olarakda bu ışınımızın rengini belirliyoruz.Eğer bu ışını Game penceresinde de görmek isterseniz, lineRenderer fonksiyonunu kullanmanız gerekiyor.Bunu daha sonraki yazılarda göreceğiz.C# Script dosyamız artık hazır.
İşte bu kadar.Bu yazımızda sonuna geldik.Raycast kullanım senaryoları çok farklılık gösterebilir.Ben anlatırken bu şekilde bir senaryo kullanmayı tercih ettim.Sizin projenizde belirlediğiniz sorulara göre, bu kullanım şekli çeşitlenebilir.Daha sonra yazacağım yazılarda yine Raycast‘an yararlanacağım.Evet bir sonraki yazıda görüşmek üzere…
Merhaba nesneleri mause ile vurma işlemlerini nasıl gerçekleştirebilirim ?
Merhaba, vurmadan kastınız eğer kuvvet uygulamaksa, Rigidbody.AddForce fonksiyonu ile nesneye kuvvet uygulanabilir.
ahmet güler harikasın sadece bunu diyebiliyorum HARİKASIN!
Merhaba, yardımcı olabildiysem ne mutlu bana. 🙂
Hocam ben 2 boyutlu bi oyun yapıyorum raycast kullanarak karakterin hareketlerini geliştiriyorum bu raycast komutunda lazer illa bi cisimle karşılaştığında mı tepki veriyor. Ben 2 lazeri birbiriyle çarpıştırmak istiyorum yapamadım bi türlü.
Merhaba dediğiniz gibi raycast, attığınız ışının katı bir nesneye çarpması sonucu tetiklenir.Sizin yapmaya çalıştığınız mekanik için yani, iki ışını (lazeri) birbirine çarpıştırmak için line renderer kullanmak daha işlevsel duruyor.Örneğin line renderer ile oluşturduğunuz lazere bir collider ekleyerek çarpışma tespitini yapmak mümkündür.Tabi collider eklemek line renderer için biraz farklı oluyor ancak çok zor bir işlem değil.