Unity’de Radar Yapımı

Unity’de Radar Yapımı

3 Şubat 2020 0 Yazar: Ahmet Güler

Merhaba bir önceki yazımızda, Unity‘de destroy fonksiyonunun kullanımına yönelik bir proje yapmıştık.Bu yazımızda yapacağımız projede ise, bir radar sistemi yapacağız.Unity‘de radar yapmanın birden çok yolu var.Örneğin, projenizde tepe noktasına yerleştireceğiniz ikinci bir kamera ile nesnelerin konumlarını iki boyutlu olarak gösterebilirsiniz.Biz bu projede bunu yapmak yerine, oyuncu ile hedef arasındaki uzaklığı hesaplayarak radarımızı oluşturacağız.Evet lafı uzatmadan projemize başlayalım.

Sahnemizin hazırlanması.

Bu projedeki senaryoya bakalım.Evet, haritamızda belli başlı hedefler olacak.Bizde radarımızı kullanarak, hedeflerin pozisyonlarını tespit edeceğiz.Tabi bu hedef nesneler, haritada saklı olmayacak.Amaç burada radar sisteminin düzgün çalışıp çalışmadığını kontrol etmek.İlk olarak bir Plane nesnesi oluşturarak başlayalım.Inspector penceresinde bu nesnemizin x ve z eksenlerindeki boyutunu arttıralım.Çünkü üzerinde hareket edeceğimiz için büyük olması gerekiyor.Şimdi sahnemize Cube nesnesini ekleyelim.

Bu nesneye Rigidbody bileşenini ekliyoruz.Daha sonra bu nesnemizi istediğimiz kadar kopyalıyoruz.Kısayol olarak, ctrl+d ile yapabilirsiniz.Bu Cube nesneleri, bizim radarda göstereceğimiz hedeflerimizi oluşturacak.Bu nesnelere farklı etiketler oluşturuyoruz.Ben, “yesil, kirmizi ve mavi” etiketlerini oluşturdum.Bunlar projeye göre çoğaltılabilir.Bu etiketleri oluşturmamızdaki amaç, radarımızda bu etiketlere göre farklı simgeler kullanacak olmamızdandır.Şimdi bu hedef nesnelerimizin, etiketlerinde bulunan rollere göre farklı material dosyaları oluşturuyoruz.Son olarak, oyuncumuzu oluşturacağız.

Bunun için Unity‘de bulunan hazır assets dosyalarından yararlanacağız.Yukarda bulunan Assets menüsüne giriyoruz.Daha sonra Import Package menüsüne giriyoruz ve Characters seçimini yapıyoruz.Açılan pencerede “import” butonuna basarak projemize dosyaları dahil ediyoruz.Daha sonra, “Standart Assets > Characters > FirstPersonCharacter > Prefabs” dosya yolunu izliyoruz.Sonra, FPSController prefab dosyasını sahnemize sürükleyip bırakıyoruz.Son olarak, radarımız için bir arkaplan ve hedef nesnelerimizin radarda gözükmesi için simgeler buluyoruz.Evet sahnemiz hazır.Son hali bu şekildedir.

unity-radar-yapımı-basic-radar-system-tutorial

Radarımız için kodlarımızı yazmaya başlayalım.

Öncelikle bir tane C# Script dosyası oluşturuyoruz ve yeni bir isim verdikten sonra sürükleyerek oyuncu nesnemizin üzerine bırakıyoruz.Şimdi editör yardımıyla açalım ve kodlarımızı yazmaya başlayalım.

public Transform MerkezKonumu;
public Texture RadarArkaplani;
public float HaritaOlcegi;
public float RadarBoyutu;
public float GorusMesafesi;
public float SimgelerinBoyutu;
private Vector2 RadarinMerkezi;
public RadarNesneleri[] RadardaBulunacakNesneler;

İlk olarak değişkenlerimizi oluşturmakla başlıyoruz.Birinci satırda, radarın hedeflere uzaklığını hesaplamak için referans alacağı bir Transform değişkeni oluşturuyoruz.İkinci satırda, radarımıza arkaplan eklemek için bir Texture değişkeni oluşturuyoruz.Üçüncü satırda, float türünde bir değişken oluşturuyoruz.Bu değişken ile haritamızı ölçeklendireceğiz.

Dördüncü satırda, ekranda gözükecek radarımızın boyutunu ayarlamak için bir değişken oluşturuyoruz.Beşinci satırda, radarımızda belirli bir mesafede simgelerin gözükmesi için bir değişken oluşturuyoruz.Altıncı satırda, radarımızda bulunan simgelerin doğru konumlandırılabilmesi için bir Vector2 değişkeni oluşturuyoruz.Son satırda ise, Radarımızda hedef olarak gözükecek nesneler için yeni bir liste oluşturuyoruz.

MerkezKonumu = gameObject.transform;
HaritaOlcegi = 2f;
RadarBoyutu = 200f;
GorusMesafesi = 40f;
SimgelerinBoyutu = 5f;

Şimdi start() fonksiyonunun içerisine bu kodları yazıyoruz.İlk satırda, değişkenimize script dosyasını eklediğimiz nesnenin pozisyonunu eşitliyoruz.İkinci satırda, radarımızın boyutuna göre haritamızı ölçeklendiriyoruz.Örneğin, ben radarımın boyutunu ikiyüz “200” olarak belirlemişim.Buna karşılık, radardaki simgelerimin doğru konumlanması içinde, ölçeğimi iki “2” olarak belirliyorum.Dördüncü satırda, hedef ile oyuncu arasındaki maksimum uzaklığı belirliyoruz.Bu değişken, radarımızda ki simgelerin hangi aralıkta gözükmesi gerektiğini belirliyor.Son satırda ise, radarımızda ki simgelerin boyutunu ayarlıyoruz.

[System.Serializable]
public class RadarNesneleri {
   public Texture RadarSimgesi;
   public string EtiketAdi;
}

Evet şimdi, yeni bir sınıf oluşturuyoruz.Bu sınıfta, radarımızda gözükecek olan nesneleri belirleyeceğiz.Bunu sınıfı az önce oluşturduğumuz liste değişkenimiz ile kullanacağız.Ama bu sınıfta bulunan elemanları kullanabilmek için, Inspector penceresinde göstermemiz gerekiyor.İşte ilk satırda bulunan, System.Serializable fonksiyonu kısaca bu işlemi yerine getiriyor.Üçüncü satırda, yeni bir Texture değişkeni oluşturuyoruz.Bu değişken ile radarımızda gözükecek olan nesnelerin simgelerini belirleyeceğiz.Dördüncü satırda, bu nesneleri ayırt edebilmek için string türünde bir değişken oluşturuyoruz.

private void RadardaHedefleriGoster(GameObject Oyuncu, Texture RadarSimgeleri) {
   Vector3 HedeflereUzaklik = MerkezKonumu.position;
   Vector3 OyuncuPozisyonu = Oyuncu.transform.position;
   float Mesafe = Vector3.Distance(HedeflereUzaklik, OyuncuPozisyonu );
   float xEksenindekiUzaklik = HedeflereUzaklik.x - OyuncuPozisyonu.x;
   float zEksenindekiUzaklik = HedeflereUzaklik.z - OyuncuPozisyonu.z; 
   float GorusAcisi = Mathf.Atan2(xEksenindekiUzaklik, zEksenindekiUzaklik) * Mathf.Rad2Deg - 270 - MerkezKonumu.eulerAngles.y;
   float xEksenindeHedefinYeri = Mesafe * Mathf.Cos(GorusAcisi * Mathf.Deg2Rad);
   float yEksenindeHedefinYeri = Mesafe * Mathf.Sin(GorusAcisi * Mathf.Deg2Rad);
   xEksenindeHedefinYeri = xEksenindeHedefinYeri * HaritaOlcegi;
   yEksenindeHedefinYeri = yEksenindeHedefinYeri * HaritaOlcegi;
   if (Mesafe <= GorusMesafesi) {
      Rect SimgelerinRadardakiKonumu = new Rect(RadarinMerkezi.x + xEksenindeHedefinYeri, RadarinMerkezi.y + yEksenindeHedefinYeri, SimgelerinBoyutu, SimgelerinBoyutu);
      GUI.DrawTexture(SimgelerinRadardakiKonumu, RadarSimgeleri);
   }
}

Radarımızda ki hedefler için yeni bir fonksiyon oluşturuyoruz.Bu fonksiyonda iki adet parametre kullanacağız.İlk parametremiz bir GameObject olacak.İkinci olarak da, bir Texture kullanacağız.Şimdi ikinci satıra bakarsak, Vector3 değişkenimize, merkez konumun pozisyonunu eşitliyoruz.Üçüncü satırda yine Vector3 değişkenimize, bu sefer oyuncu nesnemizin pozisyonunu eşitliyoruz.Dördüncü satırda Distance fonksiyonu ile, aralarındaki uzaklığı hesaplıyoruz.

Beşinci satırda x eksenindeki uzaklığı hesaplarken, altıncı satırda ise z ekseninde ki uzaklığı hesaplıyoruz.Yedinci satırda, LookAt fonksiyonunun yaptığı işleme benzer bir işlem yapıyoruz.Yalnız burada yaptığımız işlem ile daha çok kontrol sağlayabiliyoruz.Kısaca, Mathf.Atan2 fonksiyonu ile radyan cinsinden tanjantını buluyoruz.Daha sonra Mathf.Rad2Deg fonksiyonu ile radyanı açıya dönüştürüyoruz.Sonra görüş için belirlediğimiz açıdan, y eksenindeki açıyı çıkartıyoruz.Sekizinci ve dokuzuncu satırlarda, x ve y eksenlerinde nesnelerin konumunu hesaplıyoruz.

Dokuzuncu ve onuncu satırlarda ise, bu konumları belirlediğimiz ölçek değeri ile çarpıyoruz.Bu bize radar üzerinde doğru bir pozisyon sağlıyor.Onbirinci satırda ise, bir koşul oluşturuyoruz.Eğer hedeflere olan mesafemiz belirlediğimiz maksimum mesafeden küçükse veya eşitse, koşulumuz gerçekleşiyor.Onikinci satırda, simgelerimizin radar üzerindeki pozisyonlarını oluşturuyoruz.Onucuncu satırda ise, DrawTexture fonksiyonu ile, bu simgeleri ekrana yazdırıyoruz.

Radar sistemimizin ekranımızda gözükmesi.

Şu an sadece radarımız için gerekli mekanikleri oluşturduk.Hali hazırda ekranımızda gözükmesi için bir şey yapmadık.Şimdi ise ekranda gözükmesi için gerekli kodları yazacağız.

public void OnGUI() {
   if(MerkezKonumu != null) {
      Rect RadarKonumu = new Rect(Screen.width - 10 - RadarBoyutu, Screen.height - 10 - RadarBoyutu, RadarBoyutu, RadarBoyutu);
      GUI.DrawTexture(RadarKonumu, RadarArkaplani, ScaleMode.StretchToFill);
      RadarinMerkezi = new Vector2(Screen.width - 10 - RadarBoyutu / 2, Screen.height -10 - RadarBoyutu / 2);
      foreach(RadarNesneleri TumNesneleriBul in RadardaBulunacakNesneler){      
         GameObject[] NesnelerinEtiketleri = GameObject.FindGameObjectsWithTag(TumNesneleriBul.EtiketAdi);
         foreach (GameObject HepsiniBul in NesnelerinEtiketleri){
            RadardaHedefleriGoster(HepsiniBul, TumNesneleriBul.RadarSimgesi);
         }
      }
   }
}

Öncelikle bir OnGUI fonksiyonu oluşturuyoruz.Aslında bu işlemi projemize Canvas ekleyerek, UI elemanları ile de yapabilirdik.İkinci satırda, bir koşul oluşturuyoruz ve eğer değişkenimiz boş değil ise koşulumuz çalışıyor.Üçüncü satırda, radarımız için ekranda konum belirliyoruz.Parantez içerisinde ilk bölüm, genişlik değerlerini hesaplıyor.İkinci bölüm yükseklik değerlerini hesaplıyor.

Üçüncü ve dördüncü bölümler ise, radarımızın boyutlarını kapsıyor.Dördüncü satırda, belirlediğimiz bu konumda radarımızı gösteriyoruz.Beşinci satırda, radarımızın merkezini hesaplıyoruz.Bu hesaba göre simgelerimiz doğru bir pozisyonda olacaklar.Altıncı satırda yeni bir foreach döngüsü oluşturuyoruz.Bu döngüyü, yazımızın başında oluşturduğumuz listeden elemanları çekerek radarımızı yansıtmak için kullanacağız.

Yedinci satırda, yeni bir GameObject listesi oluşturuyoruz.Bu listeye, belirlediğimiz tüm etiketlerdeki nesneleri çekiyoruz.Bunu FindGameObjectsWithTag fonksiyonu ile yapıyoruz.Sekizinci satırda yeni bir foreach döngüsü oluşturuyoruz.Bu döngüde de radarda gözükecek hedefler için oluşturduğumuz fonksiyonda, hedef yerlerini simge ile gösteriyoruz.Evet script dosyamızı oluşturduk.

Evet projemizde script üzerinde belirlediğimiz değişkenlerden, radardan gözükecek simgeler ve etiketlerini belirliyoruz.Bu listeye istediğimiz kadar etiket ve simge ekleyebilirsiniz.Burada dikkat etmeniz gereken, etiket isimlerini doğru girmeniz.Aksi takdirde hata mesajı alacaksınız.Bu projemizin de sonuna geldik.Bir sonraki yazıda görüşmek üzere…

unity-radar-yapımı-basic-radar-system-tutorial