Unity Basit Diyalog Sistemi Yapımı (Dialogue System)

Unity Basit Diyalog Sistemi Yapımı (Dialogue System)

4 Mayıs 2020 4 Yazar: Ahmet Güler

Merhaba, bir önceki yazımda Unity‘de Split Screen yapımını öğrenmiştik.Böylelikle yapmış olduğunuz projelere aynı anda en az iki oyuncuyu dahil edebiliyorduk.Bügünkü dersimizde ise, Unity‘de diyalog sisteminin nasıl yapıldığını öğreneceğiz.Yazının başlığından da anlaşıldığı üzere, gayet basit bir diyalog sistemi oluşturacağız.Şimdi vakit kaybetmeden Unity‘de yeni bir proje oluşturalım ve dersimize başlayalım.

Sahnemizi hazırlamaya başlayalım.

İlk olarak bu projede kullanacağımız senaryoyu belirleyelim.Bu projede basit bir pazar alanımız olacak.Sahnemize yerleştirdiğimiz iki tezgah ile etkileşime geçerek projemizi tamamlamış olacağız.Şimdi sahnemize yeni bir Plane nesnesi oluşturalım.Bu nesne bizim zeminimizi oluşturacak.Daha sonra tezgahlarımızı oluşturmamız gerekiyor.Bunun için Unity‘de bulunan nesneleri kullanabiliriz.

Yalnız ben, internette bulduğum 3D modellerden yardım alacağım.Tercihiniz her iki yönde de olabilir.Çünkü model de kullansanız, hali hazırdaki nesneleri de kullansanız aynı adımları izleyeceğimiz için bir sorun olmayacaktır.Etkileşime geçeceğimiz nesneleri sahnemize yerleştirdikten sonra, Inspector penceresine geliyoruz.Burada Box Collider bileşeninin altında yer alan, “Edit Collider” butonuna tıklıyoruz.Daha sonra Scene penceresinde yeşil renkte gözükecek sınırları faremiz ile tutup genişletiyoruz.

Bunu genişletme işlemini kendinize göre ayarlayabilirsiniz.Bunu yapmamızın nedeni, oyuncumuz bu sınırların içerisine girdiği zaman diyalog penceresini açmak içindir.Kodlamaya geçtiğimiz zaman daha iyi anlayacağınızı umuyorum.Şimdi sınırlarımızı belirledikten sonra “Edit Collider” butonunun altında yer alan Is Trigger kutusunu aktif ediyoruz.Böylece oyuncumuz görünmez bir duvara çarpmış gibi olmayacak.

Unity-Basit-Diyalog-Sistemi-Yapımı-How-to-make-a-Dialogue-System

Aynı işlemleri diğer etkileşime geçeceğimiz nesne içinde gerçekleştiriyoruz.Evet tezgahlarımız hazır.Şimdi projemizde kullanmak için bir oyuncuya ihtiyacımız var.Bunun içinde Unity‘de bulunan Standard Assets‘leri kullanacağız.Unity’nin üst menüsünde yer alan “Assets” menüsüne tıklıyoruz.

Daha sonra Import Package > Characters yolunu izliyoruz.Açılan pencerede “Import” butonuna basıyoruz.Project penceremize gelen klasörde sırasıyla, Standart Assets>Characters>FirstPersonCharacter>Prefabs yolunu izliyoruz.Son olarak, Prefab nesnemizi Scene penceresine sürükleyerek bırakıyoruz.Artık oyuncu nesnemiz hazır.

Unity-Basit-Diyalog-Sistemi-Yapımı-How-to-make-a-Dialogue-System

Diyalog penceremizi oluşturalım.

Şimdi diyalog sistemimiz için, arayüz (UI) elemanlarımızı hazırlamaya başlayalım.Bunun için ilk olarak bir Canvas elemanına ihtiyacımız var.Hierarchy penceresinde sağ tıklıyoruz ve UI>Canvas yolunu izliyoruz.Her çözünürlükte arayüz elemanlarımızın aynı gözükmesi için, Inspector penceresinde “Canvas Scaler” bileşenine geliyoruz.UI Scale Mode ayarını, “Scale With Screen Size” seçeneğine getiriyoruz.

Daha sonra aşağıda açılan bölüme istediğimiz bir çözünürlük değerini giriyoruz.Şimdi Canvas elemanımızın üzerine sağ tıklayarak bir Panel ekliyoruz.Bu panel bizim diyalog penceremizin arkaplanını oluşturacak.Burada varsayılan olarak şeffaf gözükecektir.Bunu düzeltmek için, Inspector penceresinde bulunan Image bileşeninde ki “Color” bölümüne tıklıyoruz ve açılan pencerede A yani Alpha özelliğinin değerini 255 yapıyoruz.Daha sonra bir Panel daha ekliyoruz.Bu paneli Scene penceresinde ayarlayarak, diyalog penceremizin başlık bölümünü oluşturuyoruz.

Bu ayarlama işlemini ve araçların ne işe yaradığını daha önceki yazılarımda detaylı olarak anlatmıştım.Bu nedenle yüzeysel geçeceğim.Scene penceresinde gördüğümüz küçük okları (Anchors) yani çapaları kullanarak, kolay bir şekilde hizalama ve boyutlandırma yapabilirsiniz.Ayarladığımız başlık bölümünün altına yeni bir Text elemanı oluşturuyoruz.Bu elemanımıza yeni bir etiket oluşturuyoruz.

Bu elemanımız, diyalog penceresinde gözükecek metnimizin başlığını oluşturacak.Diyalog penceremizi kapatmak içinde bir elemana ihtiyacımız var.Bunun için bir Button elemanı oluşturuyoruz.Bu butona vereceğimiz görev ile, diyalog penceremizi istediğimiz zaman kapatabileceğiz.Diyalog penceremizin başlık bölümü tamamlandı.Şimdi asıl metnin olacağı yeri yapalım.Bunu için yeni bir Text elemanı oluşturuyoruz.Sonra elemanımıza yeni bir etiket oluşturuyoruz.

Bu elemanın sınırlarını Scene penceresindeki kancaları kullanarak belirliyoruz.Bu şekilde ekranda gözükecek metnimiz, diyalog penceresinin dışına taşmayacaktır.Son olarak diyalog metinleri arasında geçiş yapmak için bir butona daha ihtiyacımız var.Yine yeni bir Button elemanı oluşturuyoruz ve istediğimiz bir konuma yerleştiriyoruz.Artık basit bir diyalog penceremiz var.

Unity-Basit-Diyalog-Sistemi-Yapımı-How-to-make-a-Dialogue-System

Kodlarımızı yazmaya başlayalım.

Şimdi script dosyalarımızı oluşturmadan önce, Hierarchy penceresinde yeni bir boş nesne oluşturuyoruz.Daha sonra bu boş nesnemize, yeni bir etiket oluşturuyoruz ve ekliyoruz.Bu nesne diyalog sistemimizi yönetecektir.Şimdi C# Script dosyalarımızı oluşturmaya başlayabiliriz.Bu projede iki adet script dosyası kullanacağız.Şimdi ilk script dosyamızı oluşturuyoruz ve editör programı yardımı ile açıyoruz.

using UnityEngine.UI;

İlk olarak arayüz elemanlarını kullanabilmek için bu kütüphaneyi script dosyamıza ekliyoruz.

public GameObject DiyalogPenceresi;
public Text BotAdi;
public Text KonusmaMetni;
public List<string> Metinler;
public int MetinNumarasi;

Şimdi kullanacağımız değişkenleri oluşturmakla başlıyoruz.İlk satırda yeni bir GameObject değişkeni oluşturuyoruz.Bu değişkenimiz ile oluşturduğumuz diyalog penceresini kontrol edeceğiz.İkinci ve üçüncü satırlarda yeni bir Text değişkeni oluşturuyoruz.Bu değişkenler ile, diyalog penceremizde bulunan yazıları kontrol edeceğiz.

Dördüncü satırda, yeni bir List değişkeni oluşturuyoruz.Bu değişkenimiz string türünde olup, diyalog penceresinde gözükecek metinleri kontrol edecektir.Son satırda ise, int (integer) türünde bir değişken oluşturuyoruz.Bu değişken, listemizdeki elemanların index numaralarını kontrol edecek.

DiyalogPenceresi = GameObject.FindGameObjectWithTag ("KonusmaKutusu");
BotAdi = GameObject.FindGameObjectWithTag ("BotAdi").GetComponent<Text>();
KonusmaMetni = GameObject.FindGameObjectWithTag ("KonusmaMetini").GetComponent<Text>();
DiyalogPenceresi.SetActive(false);

Şimdi bu kodları start() fonksiyonumuzun içerisine yazıyoruz.İlk satırda bulunan değişkenimize, etiketi “KonusmaKutusu” olan nesnemizi tanımlıyoruz.İkinci satırdaki değişkenimize etiketi “BotAdi” olan nesnemizin, Text bileşenini tanımlıyoruz.Üçüncü satırdaki değişkenimize ise etiketi “KonusmaMetini” olan nesnemizin, Text bileşenini tanımlıyoruz.Son satırda ise “DiyalogPenceresi” değişkenimize tanımlı nesnemizi, sahnemizde gizliyoruz.

public void MetiniGoster() {
   KonusmaMetni.text = Metinler[MetinNumarasi];
}

Şimdi yeni bir fonksiyon oluşturuyoruz.Bu fonksiyon ile diyalog penceremizde gözükecek metinleri kontrol edeceğiz.İkinci satırda “KonusmaMetni” değişkenimizin değerini, “Metinler” listemizdeki ilgili index numarasına sahip metine eşitliyoruz.Böylece ekranda, seçili metin gözüküyor.

public void SonrakiMetin() {
   if (MetinNumarasi < Metinler.Count-1) {
      MetinNumarasi++;
      MetiniGoster();
   }
}

Yeni bir fonksiyon daha oluşturuyoruz.Bu fonksiyonu oluşturmamızdaki amaç ise, “Metinler” listemizde yer alan bir sonraki metni görebilmek.İkinci satıra bakacak olursak, yeni bir koşul oluşturuyoruz.Eğer “MetinNumarasi” değişkenimizin değeri, “Metinler” listemizin değerinden küçük ise koşulumuz içerisinde bulunan kodları çalıştırıyor.

Burada yer alan “-1” değeri ise, listedeki son elemanı işaret etmek için kullanıyoruz.Aksi takdirde hata verecektir.Üçüncü satırda, “MetinNumarasi” değişkenimizin değerini bir “1” arttırıyoruz.Bunu “MetinNumarasi += 1” olarak da yazabilirdik.Dördüncü satırda ise, “MetiniGoster()” fonksiyonumuzu çağırıyoruz.

public void KonusmayiSonlandir() {
   DiyalogPenceresi.SetActive(false);
}

Şimdi diyalog penceremizi kapatmak için bir fonksiyon oluşturuyoruz.Hatırlayacak olursak, start() fonksiyonu içerisinde bu penceremizi zaten kapatmıştık.Ancak diyalog penceresi aktif olduktan sonrada, istediğimiz zaman kapatmak için bir fonksiyona ihtiyacımız var.İkinci satıra bacak olursak, “DiyalogPenceresi” değişkenimize tanımlı nesnemizi, sahnemizde gizliyoruz.Bunu yapmak içinde, SetActive fonksiyonundan yardım alıyoruz.

public void KonusmayaBasla(string BotIsimi, List<string> Metin) {
   BotAdi.text = BotIsimi;
   Metinler = new List<string>(Metin);
   DiyalogPenceresi.SetActive(true);
   MetinNumarasi = 0;
   MetiniGoster();
}

Bu aşamaya kadar gerekli fonksiyonlarımızı oluşturduk.Ancak son bir fonksiyon daha oluşturmamız gerekiyor.Çünkü etkileşime geçtiğimiz zaman diyalog penceremizi hazırlamamız gerekiyor.Bu fonksiyon ile de bunu sağlıyoruz.Burada dikkat ederseniz, diğer fonksiyonlardan farklı olarak bu fonksiyonumuzda parametre kullanıyoruz.

Çünkü diyaloglar, etkileşime geçtiğimiz nesneler tarafından oluşturulacağı için dinamik olarak listemizi güncellememiz gerekiyor.Böylece hep aynı metinleri görmeyeceğiz.İkinci satırda “BotAdi” değişkenimizin değerini, parametrede yer alan string türündeki “BotIsimi” değişkenine eşitliyoruz.Böylece etkileşime geçtiğimiz zaman buradaki ismin değiştiğini göreceğiz.Üçüncü satırda “Metinler” değişkenimizin değerini, yine parametre yer alan List değişkenimizin değerlerine eşitliyoruz.

Dördüncü satırda ise, “DiyalogPenceresi” değişkenimize tanımlı nesnemizi, sahnemizde aktif ederek gösteriyoruz.Beşinci satırda, “MetinNumarasi” değişkenimizin değerini sıfıra “0” eşitliyoruz.Böylece her diyalog penceresi aktif olduğu zaman, metinler ilk baştan gösterilmeye başlıyor.Son satırda ise, “MetiniGoster()” fonksiyonumuzu çağırıyoruz.Evet ilk script dosyamız hazır duruma geldi.

NPC’ler için kodlarımızı yazmaya başlayalım.

Şimdi ikinci script dosyamızı oluşturuyoruz ve editör yardımı ile açıyoruz.

public string BotAdi;
public GameObject DiyalogYoneticisi;
public diyalog DiyalogScripti;
public List<string> BotunMetinleri = new List<string>();

Yine script dosyamızda kullanacağımız değişkenleri oluşturmakla başlıyoruz.İlk satırda, string türünde bir değişken oluşturuyoruz.Bu değişken ile, etkileşime girdiğimiz botların ismini çekebileceğiz.İkinci satırda yeni bir GameObject değişkeni oluşturuyoruz.

Bu değişken ile, ilk script dosyamızın eklendiği nesnemizi kontrol edeceğiz.Üçüncü satırda ise, ilk script dosyamızı kontrol etmek için bir değişken oluşturuyoruz.Son satırda ise, string türünde bir liste oluşturuyoruz.Bu listede ise, NPC’lerin metinlerini kontrol edeceğiz.

DiyalogYoneticisi = GameObject.FindGameObjectWithTag ("DiyalogYoneticisi");
DiyalogScripti = DiyalogYoneticisi.GetComponent<diyalog>();

Şimdi start() fonksiyonumuzun içerisine bu kodları yazıyoruz.İlk satırda “DiyalogYoneticisi” değişkenimize, etiketi “DiyalogYoneticisi” olan nesnemizi tanımlıyoruz.İkinci satırda ise “DiyalogScripti” değişkenimizin değerini, etiketi “DiyalogYoneticisi” olan nesnenin “diyalog” bileşenine eşitliyoruz.Bunları yapmamızdaki amaç, hem projemiz başladığı zaman script dosyamız tekrar tekrar çağrılmayacak.Hemde, projemizin başlangıcında otomatik olarak yerlerine eklenecek.

public void OnTriggerEnter(Collider Kontrol) {
   if (Kontrol.gameObject.tag == "Player") {
      DiyalogScripti.KonusmayaBasla(BotAdi, BotunMetinleri);
   }
}

Sahnemizi oluştururken, etkileşime geçeceğimiz nesnelerin Box Collider bileşenlerindeki sınırları ayarlamıştık.Böylece görünmez bir sınıra girdiğimiz zaman diyalog penceresi otomatik olarak açılacaktı.İşte OnTriggerEnter fonksiyonu ile bunu sağlayacağız.İkinci satırda yeni bir koşul oluşturuyoruz.

Eğer etiketi “Player” olan bir nesne sınırların içerisine girerse, koşulumuz doğru oluyor.Üçüncü satırda, “DiyalogScripti” değişkenimizde tanımlı olan script dosyasını çağırıyoruz.Daha sonra bu script dosyasında tanımlı olan KonusmayaBasla() fonksiyonuna erişerek, parametrelerini ekliyoruz.Böylece her botun kendi metni ve ismi diyalog penceresinde gözüküyor.

public void OnTriggerExit(Collider Kontrol) {
   if (Kontrol.gameObject.tag == "Player") {
      DiyalogScripti.KonusmayiSonlandir();
   }
}

Şimdi bu sınırlardan çıkarsak diyalog penceremizin otomatik kapanmasını ayarlayalım.Bunun için, OnTriggerExit fonksiyonumuzu kullanıyoruz.İkinci satırda yeni bir koşul oluşturuyoruz ve etiketi “Player” olan nesne sınırlardan çıkarsa, içindeki kodları çalıştırıyoruz.

Üçüncü satırda, “DiyalogScripti” değişkenimizde tanımlı olan script dosyasını çağırıyoruz.Daha sonra bu script dosyasında tanımlı olan KonusmayiSonlandir() fonksiyonunu çağırıyoruz.Böylece diyalog penceremiz kapanmış oluyor.Evet bu şekilde ikinci script dosyamızda tamamlanmış oldu.

Şimdi C# Script dosyalarımızı gerekli nesnelerimize eklemeye başlayalım.İlk script dosyamızı, Hierarchy penceresinde oluşturduğumuz boş nesnemizin üzerine sürükleyerek bırakıyoruz.İkinci script dosyamızı ise, etkileşime gireceğimiz nesnelerin üzerlerine sürükleyerek bırakıyoruz.Daha sonra “Bot Adı” ve “Botun Metinleri” bölümleri istediğimiz gibi dolduruyoruz.Evet bu projemizin de sonuna geldik.Bir sonraki yazıda görüşmek üzere…

Unity-Basit-Diyalog-Sistemi-Yapımı-How-to-make-a-Dialogue-System