Evet şimdi sıra geldi, benim düşünceme göre oyun yapmak için en kritik konulardan biri olan yapay zeka konusuna. Artificial intelligence-AI yani yapay zeka sayesinde oyunumuzda yer alan objelere belirli komutlar ve kurallar vererek oynanabilirliği arttırması diyebiliriz. Tabi bu en basit tabiri olacaktır.
Örneğin Counter-Strike CS:GO oyununda yer alan botlar, zombi oyununda üzerinize gelen zombiler birer yapay zeka ürünüdür. Belirli bir alana girdiğinizde üzerinize zombi gelmesi arka tarafta size saldıran zombilere karakter bu alana girince ya da bu kadar yaklaşırsa saldır dememiz aslında basit bir yapay zeka örneği olacaktır. Başka bir örnek olarak Okey, Satranç ve Go gibi bilgisayara karşı yapılan masa oyunlarında da aynı durum söz konusu. Sizin yapacağınız hamleyi ve ileride yapabileceğiniz hamleleri ön görerek karşı hamlede bulunmasıda ileri seviye bir yapay zeka örneği olacaktır.
Zaten bildiğiniz konularda kafanızı şişirmeden konuya girmek istiyorum çünkü oldukça uzun bir yazı olacak gibi duruyor. İlk konumuz Unity yapay zeka içerisinden Navigation dersleri olacak.
Unity Navigation Kullanımı
Unity yapay zeka mantığını anlamamız için ilk öğrenmemiz gereken konu Unity Navigation konusudur. Unity Navigation sayesinde seçtiğimiz objeyi sahnemizde belirli bir noktadan farklı bir noktaya en kısa sürede gidebileceği yolun hesaplamasını yapabiliriz. Tabi belirlediğimiz kurallar içersinde bu yolu hesaplamasını sağlayabiliyoruz.
Bunu arabalarda adres bulmak için kullandığımız navigasyon sistemleri gibi düşünebilsiniz. Size en kısa mesafede gidebileceğiniz rotayı çıkarması ve trafik durumuna göre hesaplama yaparak en kısa süreyi bulması gibi düşünebilirsiniz. Aslında neredeyse birebir aynı mantık 🙂
Şimdi Unity navigasyon sistemi için bir sahne tasarladım. Sahne de yer alan yollar için Asset Store üzerinde yer alan “Small Town America – Streets – FREE” paketini kullandım.
Sahne tasarımıyla uğraşmamanız için aşağıdaki adreste yer alan paketi indirerek Unity’e import edebilirsiniz.
Sahneyi import ettikten sonra ilk yapmamız gereken “Window > AI > Navigation” menüsünden navigasyon pencesini açmak. Paketi indirdikten sonra naviasyon pencesini açtığımızda aşağıdaki gibi bir görüntü elde etmeniz lazım.

Şimdi basit bir örnek olacak. Kırmızı bayrağın olduğu yerde 3 adet objemiz var ve biz navigasyon işlemini oluşturarak objelerin en kısa yolu bulmasını sağlayarak yeşil bayraklı olan yerde bulunan kübe gelmesini sağlayacağız. Sonraki aşamalarda bazı yolları geçilemez işaretleyerek nasıl hareket edeceklerini yorumlayarak çeşitli işlemler yapacağız. Önce
Çevre elemanları içerisinde yer alan tüm objeleri static duruma getirerek sahnede sabit olbjeler olduğu belirtmemiz gerekiyor. Eğer sahneyi import ettiyseniz otomatik olarak seçilmiş olarak gelecektir. Eğer siz kendiniz bir sahne oluşturduysanız aşağıdaki gibi “Inspector” alanındaki “Static” kısmından “Navigation Static” olarak seçebilirsiniz.

Navigation Bake Ayarları
Şimdi hesaplamayı yapması için Navigation penceresinin altında yer alan “Bake” bölümüne geçerek “Bake” butonuna basıyoruz. Böylece navigasyon ajanlarının(Başlangıç noktasındaki kapsüller) geçebileceğiz yol haritasını çıkartacağız.

“Bake” butonuna bastıktan sonra yukarıdaki resimdeki gibi ajanların hareket edebileceği alanların turkuaz-mavi arasında bir renk olduğu göreceksiniz. İşte bu alanlar ajaların geçebileceği alanlar oluyor. Kendi renginde kalanlar ise üzerinden ajanın geçemediği alanlardır.
Ajanların yürüyebileceği, sığabileceği, zıplayabileceği ve tırmanabileceği alanları yani bizim belirlediğimiz kurallara uyanları göstermektedir.
Peki bu kuralları nasıl belirliyoruz?
Bu işlem için iki bölümümüz bulunuyor. Biri ajan bazlı bir belirleme diğeri ise “Bake” işlemi sırasında belirleyeceğimiz maksimum değerlerin olduğu kısım.
İlk önce “Bake” kısmında yer alan ayarlara bir göz atalım. Fakat unutmayın Bake maksimum değerlerin belirlendiği ayarlar “Agents” kısmında yer alanlar ise ajan bazlı olarak verilen ayarlardır.
- Agent Radius: Bir ajanın merkezinin bir duvara ya da çıkıntıya ne kadar yakın olabileceğinin belirlendiği kısımıdır. Bir ajanın belirlediğimiz bir yürüme alanının kenarlarına ne kadar yaklaşabileceğini belirlediğimiz kısım diye düşünebilirsiniz.

Örneğin yukarıda resimde görüldüğü gibi Agent Radius ayarını arttırdığımızda ajanımızın gezebileceği alanlar genişliğinden dolayı sınırlanmış oldu. Bir nevi kaldırımları belirlemiş olduk 🙂
- Agent Height: Bir ajanın geçebileceği alanların maksimum yüksekliğinin belirlendiği kısımdır.

Resimde gözüktüğü gibi sahnemizde “Agent Height” alanının değeri yüksek olduğu için ok ile gösterilen geçittin altından geçemeyecek duruma gelmiştir.
- Max Slope: Bir ajanın tırmanabileceği rampanın ne kadar yüksek olabileceğinin belirlendiği kısımdır.

Görüldüğü gibi eğim çıkma oranını düşürdüğümüzde resimdeki rampanın çıkış kısmı ajanın yürüyebileceği alanlardan çıkarılmıştır.
- Step Height: Ajanın basabileceği engellerin yüksek sınırlamasının yapıldığı kısımdır. Adım atma yüksekliği olarak düşünebilirsiniz.

- Drop Height: Bir ajanın maksimum ne kadar yükseklikten inebileceğinin belirlendiği kısımdır.
- Jump Distance: Bir ajanın maksimum ne kadar yüksekliğe çıkabileceği kısımdır.
Navigation Agents Ayarları
“Navigasyon” penceresinin altındaki “Agents” yani ajanlar sekmesini açıyoruz. Bu ekranda varsayılan olarak gelen “Humanoid” ajan ayarlarının ve grafiksel olarak sonuçları gösteren bir panel göreceksiniz.

Ekranda yer alan “+” tuşuna basarak yeni bir ajan ekleyelim. Sonrasında ise aşağıdaki gibi bazı ayarlar göreceksiniz. Bu alandan ajanların karakteristik özelliklerini ayarlayabiliyoruz diyebiliriz. Biraz detaylıca inceleyelim.
- Name: Ajana isim belirlediğimiz kısım.
- Radius: Ajanın yarıçapının belirlendiği kısım.
- Height: Ajanın boyunun belirlendiği kısım.
- Step Height: Ajanın adım atma yüksekliğinin belirlendiği kısım.
- Max Slope: Ajanın çıkabileceği eğim oranının belirlendiği kısım.
3 tane ajanımız için farklı farklı ajan tanımlamaları oluşturduk ve bunları objelerimize atayarak, objelerin ajan görevinde olmasını sağlamak. Bunun için objelerimize “Nav Mesh Agent” bileşenini ekleyeceğiz. Bileşeni ekledikten sonra “Agent Type” alanından oluşturduğumuz ajan tanımlamalarını seçmemiz gerekiyor.

Evet “Nav Mesh Agent” bileşeni aldın da birçok ayar var ama bu ayarları görmeden önce burada bilmeniz gereken önemli bir konu var.
Eğer birden fazla Agent Type oluşturur ve farklı objelere, farklı ajan türleri eklerseniz sadece bir ajanınız hareket edecek ve aşağıdaki gibi bir hata alacaksınız.
“Failed to create agent because it is not close enough to the NavMesh.
Bunun sebebi sadece bir ajan için bir mesh yapısı yani harita oluşturulabilmesi. Ama bizim farklı özelliklere sahip bir ajan için farklı bir harita oluşturmamız gerekiyor.
Evet bu yüzden çalışmaması mantıklı ama bana sorarsanız aslında bu bir bug. Bu yapılandırmanın oyun motoru üzerinden varsayılan olarak yapılabilmesi gerektiğini düşünüyorum. Neyse ki Unity bunun için resmi git sayfasında bir çözüm paylaşmış.
Bunun için aşağıdaki adresten NavMesh Surface bileşenini indirerek Unity’e indirmemiz gerekiyor. Bu kısım biraz daha teknik olduğu için ileri ki aşamalarda bir içerik hazırlayacağım.
https://github.com/Unity-Technologies/NavMeshComponents
Evet biraz konu dağıldı. Şimdi toparlıyorum merak etmeyin.
Tüm ajanlarımıza yani başlangıçta yer alan objelere “Nav Mesh Agent” bileşenini ekliyoruz ve “Agent Type” ayarını “Humanoid” ve “Speed” kısmını “35” olarak olarak değiştiriyoruz. Aşağıdaki gibi başlangıçta yer alan tüm objelere de aynı işlemi yapacağız.

Sonrasında ise “Navigation” penceresinden “Bake” butonuna basarak tekrar bir harita çıkartıyoruz.
Ajanları Hareket Ettiriyoruz
Şimdi ajanlarımıza biraz hareket katmak gerekiyor. Bunun için işin içine biraz C# eklemenin zamanı geldi.
Ajan görevinde olacak objelerimize “AjanAyarlari” isminde bir C# script dosyası ekleyerek, script içerisine aşağıdaki kodları yazalım.
using UnityEngine; using UnityEngine.AI; public class AjanAyarlari : MonoBehaviour { public GameObject hedefimiz; private NavMeshAgent ajan; private void Start() { ajan = transform.GetComponent<NavMeshAgent>(); } void Update() { ajan.SetDestination(hedefimiz.transform.position); } }
Peki neler yazdık?
- NavMeshAgent sınıfını kullanabilmek için
using UnityEngine.AI;
yazarak namespace ekledik. - Dışarıdan hedefimizi belirlemek için
public GameObject hedefimiz;
yazdık. - Oyun başladığında atamasını yapması için Start metodunun içerisine
ajan = transform.GetComponent<NavMeshAgent>();
yazdık. Böylece ajanlara eklediğimiz bileşenlere erişebileceğiz. - Son olarak ise
ajan.SetDestination(hedefimiz.transform.position);
yazarak NavMeshAgent bileşeni ekli olan ajana hedef olarak tanımlanmış olan objenin pozisyonuna gitmesini söylemiş olduk.
Kodlarımızı eklediğimiz objeleri seçerek hedef kısımlarına dışarından obje tanımlaması yapmayı unutmayın. Bunun için hedef olarak belirlediğimiz objeyi tanımlıyoruz.

Şimdi oyunu çalıştırdığınızda aşağıdaki gibi bir çıktı almamız lazım. Tüm ajanlar sağdan ya da soldan gitmek yerine en kısa olan yolu yani ortada ki yolu seçiyorlar.
Peki şimdi “Navigation” menüsünde yer alan “Bake” ayarlarını aşağıdaki gibi değiştirelim ve tekrar hesaplama yapması için tekrar “Bake” tuşuna basalım.

Ayarlarda biraz rampa çıkmasını ve adım atma yüksekliğini düşürdüğümüz için orta yoldaki engeli çıkamıyor ve sağ yolda bulunan engelin üzerine adım atamadığı için en uzun yolu yani sol taraftaki yolu seçiyor Unity yapay zekamız.
Yani burada direk ajanında özelliklerini değiştirebilirsiniz ya da maksimum değerler için bake ayarlarını da. Ama mantık basit, eğer ajanlarımızın özelliklerine uymayan bir koşul varsa hesaplamaları otomatik olarak yaparak yeni bir rota çıkartıyorlar.
Nav Mesh Agent Ayarları
Örneğimizde kullandığımız Nav Mesh Agent bileşeninin parametreleri sayesinde ajanımızın davranışlarını biraz daha şekillendirebiliriz. O zaman hem ayarları inceleyelim hem de sonrasında bir kaç örnek çalışma gerçekleştirelim.

Agent Type: Ajan tipinin seçilebileceği alandır.
Base Offset: Her ajanın sahnede yer alacağı diğer objelerle etkileşime gireceği bir alan sınırı bulunmaktadır. Base Offset ayarı ile bu alanın pivot noktasını belirleyebilirsiniz.
Speed: Ajanın hızının ayarlandığı kısımdır yani ajan belirlenen hedefe giderken ne kadar hızlı gitsin ayarlayabiliriz.
Angular Speed: Ajanın hedefe giderken ki maksimum dönüş hızını ifade etmektedir. Ajanın hızı ve ivmesi ile beraber kullanılır.
Acceleration: Ajanın hızlanma ivmesini ifade eder. Ajana verilen hıza ulaşması için gerekli olan ivmedir. Bir arabanın 0’dan 100 km hıza çıkmasını düşünebilirsiniz.
Stopping Distance: Ajan hedefe ne kadar mesafede duracağının belirlenmesi için kullanılır. Örneğin oyundaki bir okçu karaktere düşmana belirli bir mesafe yaklaştıktan sonra ateş etmeyi ayarlamayı düşünebilirsiniz.
Auto Braking: Ayar seçili olarak kullanılırsa ajan, hedefe varmak üzereyken yavaşlayacaktır. Örneğin belirli bir döngüde sürekli ileri, geri gelen bir engel kullanıyorsanız ayarın kapalı tutulması gerekecektir.
Radius: Ajanın etrafında engel alanı oluşturur. Ajan için belirtilen alana diğer objelerin girmesini engellemek için kullanılır.
Height: Radius ayarında olduğu gibi yükseklik olarak ajan için bir engel alanı oluşturur.
Quality: Engelden kaçınma kalitesinin belirlendiği kısımdır. Low, Medium, Good ve High şeklinde dört farklı ayarı bulunmaktadır. Örneğin Low Quality ayarında engelden kaçınırken biraz daha tolerans gösterecektir. Ne kadar yüksek ayar kullanılırsa, o kadar çok hesaplama yapacağı için işlemciyi daha çok zorlayacaktır.
Priority: Kaçınma için öncelik verilebilen kısımdır. Daha düşük değer verilmiş ajanlar daha önceliktir. Şöyle düşünebilirsiniz bir savaş oyununda atlı ve okçu birlikleriniz varsa atçı birliklere sıfır ve okçulara bir değeri vererek sıraya koymak diye düşünebilirsiniz.
Auto Traverse Off Mesh Link: Mesh edilmemiş yani haritanın dışında kalan alanların hesaplanması için işaretli kalması gerekmektedir.
Auto Repath: Ajanın hedefe ulaşabilecek en yakın mesafeye gitmesi için işaretli olmalıdır. Örneğin ajan farklı bir yerdeyse ve hedefe ulaşamıyorsa, en yakın mesafeye gidecektir.
Area Mask: Belirli bölgeleri maskelemek için kullanılan bölümdür. Birazdan bu kısma detaylı değineceğiz.
Navigation Areas Ayarları
Sahnemizde ajanımızın hareket edebileceği yolları hesaplayarak haritasını oluşturabiliyoruz. Ayrıca ajanımızın özelliklerini değiştirerek haritada ki belli alanları kullanamamasını da sağlayabiliyoruz. Fakat bu işlemler sırasında biraz limitli imkanlarımız var.
Area özelliği sayesinde sahne üzerinde yer alan bölgeler için bir hesaplama mantığı oluşturarak ajanlarımızın hareketlerini manipüle edebiliriz.

Navigation penceresinin altında yer alan Areas sekmesinin içinde yukarıdaki gibi bir ekran göreceksiniz. Bu alan içerisinde Unity tarafından hazır olarak eklenen “Walkable“, “Not Walkable” ve “Jump” gibi tanımlamalar bulunmaktadır. Bu tanımlamalar isimlerinden de anlaşılacağı gibi aşağıdaki anlamlara geliyor.
Walkable – Yürünebilir Alan
Not Walkable – Yürünemeyen Alan
Jump – Zıplanabilir Alan
Tabi bu standart ayarların haricinde kendimizde yeni tanımlamalar ekleyebiliyoruz. Ama bunun öncesinde bu tanımlamaları nereden değiştirebileceğimize bakalım.

Sahnede bulunan alanlarınızdan birini seçtikten sonra yukarıdaki gibi “Navigation > Object > Navigation Area” kısmından mevcut tanımlamaları ya da eklediğiniz tanımlamaları görebilir ve değiştirebilirsiniz. Örneğin bu alanı “Not Walkable” olarak değiştirirsek ajanlarımız hedefe giderken sahnenin bu kısmını kullanamayacaklardır. Ayrıca her alan değişikliğinden sonra “Bake” yaparak yeniden hesaplama yapmayı unutmayın.
Bu işlemleri test etmek için basit bir örnek hazırladım. Sahne tasarımını bu bağlantıdan indirebilirsiniz.

Sahnede yer alan iki adet kapsülümüz yani ajanımız küp objesine yani hedefe gitmeye çalışacaklar. Ama biz burada ajanların seçeceği yolları değiştirerek farklı alternatifleri kullanmasını sağlayacağız.
Bu işlem için “Navigation > Areas” altından yeni bir alan oluşturuyoruz ve köprü olarak gözüken objelere bu oluşturduğum tanımlamayı ekledikten sonra “Bake” işlemi ile yeniden hesaplamasını yapıyoruz.
Şimdi ise ajanlarımıza hangi alanlardan gidebileceklerini söylememiz gerekiyor. Örneğin somon rengi olan Ajan2 objemize tıklayarak “Inspector” alanından “Nav Mesh Agent” bileşeni ayarları altındaki “Area Mask” seçeneği kaldırıyoruz. Böylece ajanımıza köprü olarak belirtilen alanlardan geçemeyeceğini belirtmiş oluyoruz.
Yukarıdaki videoda gördüğünüz gibi ajanımız köprüyü kullanmayarak farklı bir yol üzerinden hesaplama yapmak zorunda kaldı. Video sırasında dikkat ettiyseniz köprüye girmeyerek yolunu değiştirdiğinde sanki yanlış bir yola girip geri dönmüş gibi gelebilir size. Bu örneği bilerek bıraktım aslında burada ajanın hızı, dönmesi gereken ilk sapak için çok hızlı olduğu için bu şekilde gözüküyor. Burada anlayacağımız yapay zekanın daha gerçekçi gözükmesi için haritanın yapısı, ajanın özellikleri gibi bir çok etkeni hesaplamanız gerekiyor.
Yukarıda yaptığımız işlemde ajan bazlı olarak belirli alanlardan geçip geçemeyeceğini belirtiyorduk. Şimdi ise alanların “Cost” yapılarını yani maliyetlerini belirterek ajanlarımızın kendilerinin seçim yapmasını sağlayacağız.
Aynı sahnede aşağıda ki görseldeki basit bir değişiklik yaptım. İki ajanımızın hedefe gidebilmesi için 4 farklı yolları bulunuyor.

Fakat biz resimde çerçeve ile belirlediğim alana bir maliyet belirterek ajanların o alanı seçmemelerini sağlayacağız. Mantığı aslında şu şekilde düşünebilirsiniz. Çerçeveye aldığım alan aslında oyununuzda yer alan bir su birikintisi. Ajanlarımızın bu alana girmesini yasaklamıyoruz. Sadece eğer buradan geçersen sana maliyeti bu olur diyerek bir seviye belirlemiş oluyoruz.
Videoda gördüğünüz gibi ajanlar “Su” olarak belirlediğimiz maliyeti göz önüne alarak uzun yoldan gitmeyi tercih ettiler. İşte aslında bu yaptığımız bir nevi yapay zeka oluyor arkadaşlar 🙂
Nav Mesh Obstacle Bileşeni
Sahnemize eklediğimiz objeleri “Static” olarak belirleyerek yeri değişemeyen objeler olduğunu belirtmiştik. Ama bir de şöyle düşünün sürekli hareket halinde olan bir objemiz var ve ajanlarımızın bu objeyi de dikkate alarak hesaplama yapmalarını isteyebiliriz.
Bunun için Unity’nin bize sunduğu bir özellik olan Nav Mesh Obstacle bileşenini kullanabiliriz.
Hemen bir örnek yaparak nasıl kullanıldığına göz atalım.
Önceli örnekte kullandığımız sahnemize bir adet küp ekledik ve mevcut olan 4 yoldan 3 tanesini bu engel ile kapattık. Sonrasında ise eklemiş olduğumuz objemizi seçerek “Nav Mesh Obstacle” bileşenini ekledik ve ayarlarından “Carve” seçeneğini de işaretledik.

Amacımız oyun içerisinde bu engeli hareket ettirerek ajanların yolu tekrar nasıl hesapladıklarını görmemiz. Burada “Bake” yani hesaplama işlemini bizim statik olarak yapmamız değil de arka planda dinamik olarak bu işlemi kendiliğinde yaptığını görmeye çalışmak olmalı.
Eğer burada “Carve” seçeneğini işaretlememiş olsaydık koyduğumuz kırmız engel objesini ajanlarımız tam olarak hesaplayamayacaktı. Burada tam olarak bahsettiğim aslında şu şekilde.
Eğer Carve seçeneği işaretli olmazsa ajanlar aşağıdaki gibi o yollardan gitmeye çalışacaktır ama engelle karşılaşınca duracaklardır ya da saçmalayacaklardır. Yani farklı bir alternatif yol bulamayacaklardır.
“Carve” içinde yer alan diğer ayarlar ise aşağıdaki gibidir.
- Move Threshold: Engelin ne kadar hareket ettiğinde hesaplanması gerektiğini belirlediğimiz kısımdır. Yani hareket ne kadar hareket ederse hesaplamasını yapacağını belirtebiliyoruz.
- Time To Stationary: Hesaplamanın ne kadar hızlı yapılacağının belirlendiği kısımdır.
- Carve Only Stationry: İlgili seçeneğin işareti kaldırılırsa engel hareket ederken bile hesaplama yapacaktır. İşaretli olarak bırakılırsa ise engel sabit olduğu zaman hesaplama yapacaktır. Anlık olarak hesaplama yapılmasının biraz performans etkisi olduğunu unutmayın.
Aslında Unity Yapay zeka konusu bu kadar kısa değil ama daha fazla beyin yakmamak için burada sonlandıracağım. İleri de belki kapsamlı örnekleri ekleyebilirim ama şuan heyecanla yeni konumuzu öğrenmeyi bekliyorum 🙂
Devamı gelecek mi?
Merhaba Ahmet, Evet baştan sona bir Tower Defense oyunu yapma üzerine bir içerik hazırlıyorum ama yüksek lisans sınavlarına denk geldiği için bir süre bekletmek durumunda kalacağım.
Gerçekten çok güzel açıklanmış. Elinize emeğinize sağlık.
Teşekkürler. Unity AI konusuna ilerleyen zamanlarda eklemeler yapacağız. Takipte kalın lütfen.
muhteşem mis gibi
State machine AI gelir mi hocam
Selam Tolga, Şuan planlamada yok ama not olarak ekliyorum.
Derslerin devamı kesinlikle gelmeli lütfen devam edin derslere çok güzel anlatıyorsunuz.
Selam Mehmet, Evet kesinlikle derslerin devamı gelecek. Sadece şuan yoğun bir süreçteyim ama arka planda birlikte yapacağımız bir oyun projesinin alt yapısını hazırlıyorum.
Çok güzel olmuş
Teşekkürler Akın 🙂
Hocam unity de oyun yapmak için kpd yazmak gerekiyormu?
Merhaba Selcen, Yapılabilir ama emin ol sadece zaman öldürmek için olacaktır. Eğer gerçekten işin içine girmek istiyorsan kod öğrenmen gerekiyor.
Rastgele şehir oyunum için trafik sistemi arıyordum seni buldum ya çok güzel açıklamışsın ve anlatmışsın çok teşekkür ederim <3
İşine yaramasına sevindim. Oyununu yapmada bol şans.
Nav Mesh Obstacle bileşenini, üzerine çalıştığım labirentin kapılarına uyguladığımda ajanları dışarıda tutuyor, ta ki kapılar açılana kadar… Aradığım tam da bu idi.. Bilgiler için teşekkürler..
Çok başarılı