Unity Split Screen Yapımı (Ekranı İkiye Bölmek)
Merhaba, bir önceki yazımda Unity ile nesne havuzu yapımını öğrenmiştik.Object Pooling yöntemi sayesinde projelerimizde sıkça kullandığımız klon nesnelerin, performans üzerindeki olumsuz etkisini minimuma indirmiş oluyorduk.Bugünkü dersimizde ise, Unity’de Split Screen yani ekranı ikiye yada ikiden daha fazla pencereye nasıl bölebileceğimizi göreceğiz.Bu sayede tek bir bilgisayar (yada farklı bir cihaz) üzerinden iki veya daha fazla kişi aynı anda oyun oynayabilecek.Şimdi lafı uzatmadan 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.Split Screen için birçok senaryo oluşturdum.Fakat Shared Screen ile karışabileceğinden, en basit olanı yani bir araba yarışı temasını uygun gördüm.Bu sayede yazının konusunun daha net anlaşılabileceğini düşünüyorum.Şimdi sahnemize nesnelerimizi eklemeye başlayabiliriz.İlk olarak bir Plane nesnesi oluşturuyoruz.
Bu nesne bizim zeminimizi oluşturacak.Daha sonra bu Plane nesnemize internetten kolaylıkla bulacağımız herhangi bir kaplamayı atıyoruz.Örneğin ben, bir asfalt kaplaması tercih ettim.Bu tercihi size bırakıyorum.Daha sonra iki kişinin ayrı ayrı kontrol edebileceği nesneleri projemize eklememiz gerekiyor.Bunun için Unity‘de bulunan hazır nesneleri de tercih edebiliriz.Yada internetten bulabileceğimiz 3D modelleri de tercih edebiliriz.
Ben görsel olarak daha iyi duracağı için tercihimi, hazır modellerden yana kullanıyorum.Şimdi kullanacağımız modelleri, projemize dahil ediyoruz.Modellerimizin ebeveyn nesnesine Inspector penceresinden Rigidbody bileşenini ekliyoruz.Daha sonra modellerimizi sahnemize sürüklüyoruz.Scene penceresinden bu modellerin konumunu yada boyutunu istediğimiz gibi ayarladıktan sonra, artık oyuncu kameralarını yerleştirebiliriz.
Bunun için, Hierarchy penceresinde bulunan ana kameramızı (main.camera) tutup ilk araba nesnemizin üzerine sürüklüyoruz.Daha sonra kamera açısını ayarlamak için, Inspector penceresinde bulunan Transform değerleri ile oynuyoruz.
Evet birinci aracımızın kamerası ayarladın.Şimdi ikinci arabamız içinde bu işlemleri yapmamız gerekiyor.Bunun için, ilk kameramızını Hierarchy penceresinde kopyalıyoruz.Oluşturduğumuz kamera kopyamızı bu sefer, ikinci araba nesnemizin üzerine sürüklüyoruz.Yine Inspector penceresinde bulunan Transform değerleri ile oynayarak, kameramızın konumu ayarlıyoruz.Sonra her iki kameramız için yeni etiketler oluşturuyoruz ve bu etiketleri kameralarımıza ekliyoruz.
Ekranı nasıl böleceğiz?
Her iki oyuncumuzun kontrol edeceği araçlar ve bu araçların kameraları projemizde hazırlanmış bulunuyor.Yalnız Game penceresinde tek bir araba görünüyor.Bunu her iki arabamızın da görüneceği şekilde ayarlamamız gerekiyor.Bunu yapmak gayet basit.Öncelikle ilk arabamızda bulunan kamerayı seçiyoruz.Daha sonra Inspector penceresinde bulunan Camera bileşeninin, Viewport Rect ayarına geliyoruz.
Bu ayar ile kameramızı ekranda istediğimiz gibi konumlandırabiliyoruz.Bu arada bu ekranı yatay yada dikey olarak bölebilmek mümkün.Ben default olarak oyunu yatay başlatmak istiyorum.Bunun için, ilk oyuncumuzu ekranın üzerinde yer alacak şekilde konumlandırıyoruz.İsterseniz altında da konumlandırabilirsiniz.Tercihi size bırakıyorum.
Evet şimdi Viewport Rect ayarlarını (X =0 Y= 0.5 W = 1 H = 0.5) bu şeklide yapıyoruz.Daha sonra ikinci kameramızı seçiyoruz.Ve aynı bölümde bu sefer Viewport Rect ayarlarını (X =0 Y= 0 W = 1 H = 0.5) olacak şekilde değiştiriyoruz.Böylece artık ekranımızda her iki aracıda görebiliyoruz.
Bu kısaltmaların ne olduğuna gelecek olursak, X (x eksenini kontrol ediyor.), Y (y eksenini kontrol ediyor.), W (width yani genişliği kontrol ediyor.) ve H (height yani yüksekliği kontrol ediyor.) Örneğin biz birinci oyuncunun alt bölümde, ikinci oyuncunun ise üst bölümde olmasını isteseydik, Viewport Rect ayarlarında bulunan Y değerini her iki kamera içinde değiştirerek istediğimizi yapmış olacaktık.Şimdi yazının önceki kısımlarında da dediğim gibi, ekranı yatay yada dikey bölebiliriz.
Şu an için yatay görünümde bulunuyor.Fakat ben bir buton ile bu ekranı istediğim zaman değiştirmek istiyorum.Bunu yapmak için Hierarchy penceresinde sağ tıklayarak, UI > Canvas seçimini yapıyoruz.Daha sonra yine aynı yolu izleyerek bir Button ekliyoruz.Scene penceresindeki araçları kullanarak bu Button nesnemizi, istediğimiz gibi ayarlıyoruz.Bu butona tıklayarak ekranı yatay yada dikey olarak bölebileceğiz.Tabi bunu yapmak için kod yazmamız gerekiyor.
Kodlarımızı yazmaya başlayalım.
Evet ilk C# Script dosyamızı oluşturuyoruz.Daha sonra bu script dosyamıza bir isim veriyoruz ve editör yardımı ile açıyoruz.
public Camera KameraBir; public Camera KameraIki; public bool EkranAyari;
İlk olarak kullanacağımız değişkenleri oluşturmakla başlıyoruz.İlk ve ikinci satırlarda Camera değişkenlerimiz oluşturuyoruz.Bu değişkenler ile sahnemizde yer alan kameraları kontrol edeceğiz.Üçüncü satırda ise bool türünde bir değişken oluşturuyoruz.Bu değişken ile de, yatay ve dikey tercihler arasında ki geçişi kontrol edeceğiz.
KameraBir = GameObject.FindGameObjectWithTag ("birinci_oyuncu").GetComponent<Camera>(); KameraIki = GameObject.FindGameObjectWithTag ("ikinci_oyuncu").GetComponent<Camera>(); EkranAyari = true;
Şimdi bu kodları start() fonksiyonunun içerisine yazıyoruz.İlk satırda değişkenimize, etiketi “birinci_oyuncu” olan kamera nesnemizin Camera bileşenini eşitliyoruz.İkinci satırda değişkenimize bu sefer, etiketi “ikinci_oyuncu” olan kamera nesnemizin Camera bileşenini eşitliyoruz.Son satırda ise, bool değişkenimizin değerini true olarak belirliyoruz.
public void EkranDegistir() { EkranAyari = !EkranAyari; }
Evet şimdi yeni bir fonksiyon oluşturuyoruz.Bu fonksiyon ile ekranımızın bölme mekaniğini kontrol edebileceğiz.İkinci satırda, bool türündeki değişkenimizin değerini değiştirmek için kodumuz bulunuyor.Bu kod ile, true yada false arasındaki geçişi kolaylıkla sağlayabiliyoruz.
if (EkranAyari) { KameraBir.rect = new Rect (0, 0.5f, 1, 0.5f); KameraIki.rect = new Rect (0, 0, 1, 0.5f); } else { KameraBir.rect = new Rect (0.5f, 0, 0.5f, 1); KameraIki.rect = new Rect (0, 0, 0.5f, 1); }
Yine bu fonksiyonumuzdan devam ediyoruz.Birinci satırda yeni bir koşul oluşturuyoruz.Eğer bool değişkenimizin değeri true ise bu kodları çalıştır, eğer tam tersi ise diğer kodları çalıştır diyoruz.İkinci satırda, ilk kamera nesnemizin “rect” değerlerini değiştiriyoruz.Üçüncü satırda ise yine aynı şekilde bu sefer ikinci kameramızın “rect” değerlerini değiştiriyoruz.
Bu değerler sırasıyla, X–Y–W–H olarak geçiyor.Beşinci satırda, ilk kamera nesnemizin “rect” değerlerini değiştiriyoruz.Dördüncü satırda ise, bu sefer ikinci kamera nesnemizin “rect” değerlerini değiştiriyoruz.Koşulumuzun true yani ilk bölümü, ekranı yatay olarak bölmek için bulunan ayarları barındırıyor.Koşulumuzun false yani ikinci bölümünde ise, ekranı dikey olarak bölmek için bulunan ayarları barındırıyor.
Oyuncu kontrollerini oluşturalım.
Evet ilk script dosyamızı hazırladık.Şimdi ikinci script dosyamızı oluşturalım.Bu script dosyamıza yeni bir isim verdikten sonra, editör yardımı ile açıyoruz.
public enum OyuncuKontrolu { YonTuslari, WASD } public OyuncuKontrolu varsayilanKontrol = OyuncuKontrolu.YonTuslari; public float ArabaHizi; public float DonusHizi;
Şimdi oyuncu kontrollerimiz için kullanacağımız değişkenleri oluşturuyoruz.İlk satırda, bir enum değişkeni oluştuyoruz.Enum fonksiyonuna daha önceki yazılarımda değinmemiştim.Bunun için ayrı olarak bir yazı yazacağım.Fakat burada da kısaca geçmek istiyorum.Enum uzun adıyla Enumerations, türkçede numaralandırma olarak geçiyor.
Bu yapı ile, oyuncu kontrollerini istediğimiz gibi ayarlayabileceğiz.İkinci satırda, enum değişkenimize bir değer atıyoruz.Üçüncü ve dördüncü satırlarda, float türünde değişkenler oluşturuyoruz.Bu değişkenler ile arabalarımızın hızını ve donus hızını kontrol edeceğiz.
ArabaHizi = 5f; DonusHizi = 30f;
Daha sonra start() fonksiyonumuzun içerisine bu kodları yazıyoruz.İlk satırda, araba hızımız için oluşturduğumuz değişkenimize bir değer veriyoruz.İkinci satırda ise bu sefer arabamızın dönüş hızı için oluşturduğumuz değişkene bir değer veriyoruz.
if ((varsayilanKontrol == OyuncuKontrolu.YonTuslari && Input.GetKey(KeyCode.UpArrow)) || (varsayilanKontrol == OyuncuKontrolu.WASD && Input.GetKey(KeyCode.W))) { transform.Translate (Vector3.forward * ArabaHizi * Time.deltaTime); }else if ((varsayilanKontrol == OyuncuKontrolu.YonTuslari && Input.GetKey(KeyCode.DownArrow)) || (varsayilanKontrol == OyuncuKontrolu.WASD && Input.GetKey(KeyCode.S))) { transform.Translate (-Vector3.forward * ArabaHizi * Time.deltaTime); }
Şimdi oyuncu kontrollerimizi yazmaya başlayalım.Bu kodları FixedUpdate() fonksiyonumuzun içerisine yazıyoruz.Daha önceki yazılarımda Update ve FixedUpdate fonksiyonları arasındaki farkı açıklamıştım.İlk satırda yeni bir koşul oluşturuyoruz.Burada “varsayilanKontrol” değişkenimizin değerine göre istediğimiz kodları başlatıyoruz.
İlk satıra bakacak olursak, yukarı ok tuşuna yada w tuşuna bassam bile aynı kod çalışacaktır.Fakat script dosyasının ekli olduğu nesnenin enum yapısında, seçili olan tuş kombinasyonuna göre bir hareket gerçekleşecektir.Örneğin klavyeden W tuşuna bastığım zaman, “WASD” seçili nesne hareket ederken, “Yön Tuşları” seçili olan nesne hareket etmeyecektir.Üçüncü satıra bakacak olursak, Translate fonksiyonu ile araba hareketini sağlıyoruz.
Bunun yerine Rigidbody ile de araç hareketini gerçekleştirebiliriz.Parantez içerisinde nesnenin gideceği yön, hız ve Timedelta.Time yer alıyor.Timedelta.Time fonksiyonu her karede aynı hızı elde etmek için önem arz ediyor.Dördüncü satırda bu sefer else if kullanıyoruz.Türkçe olarak, bu olmazsa buna bak diyoruz.Bu koşulda ise kısaca, klavyeden s veya aşağı oka basılırsa ne olacağını belirliyoruz.
if ((varsayilanKontrol == OyuncuKontrolu.YonTuslari && Input.GetKey(KeyCode.RightArrow)) || (varsayilanKontrol == OyuncuKontrolu.WASD && Input.GetKey(KeyCode.D))) { transform.Rotate(Vector3.right * DonusHizi * Time.deltaTime); }else if ((varsayilanKontrol == OyuncuKontrolu.YonTuslari && Input.GetKey(KeyCode.LeftArrow)) || (varsayilanKontrol == OyuncuKontrolu.WASD && Input.GetKey(KeyCode.A))) { transform.Rotate(-Vector3.right * DonusHizi * Time.deltaTime); }
FixedUpdate() fonksiyonumuzun devamına bu kodları yazıyoruz.Yukarıdaki kod blogunda geçerli olan şeyler burada da mevcuttur.Sadece koşul gerçekleşmesi için gereken klavye tuşları ve koşul gerçekleştik sonra olacaklar farklılık gösteriyor.Dördüncü satıra bakacak olursak, Rotate fonksiyonundan yardım alıyoruz.
Böylece aracımızı istediğimiz yönde döndürebiliyoruz.Yine parantez içerisinde döneceği yön, hızı ve Time.deltaTime fonksiyonu yer alıyor.Dördüncü satırda tekrar bir else if kullanıyoruz.Böylece nesnelerimizin sağa ve sola dönüşleri için gereken mekanikleri oluşturmuş oluyoruz.
Evet projemizi tamamlamış bulunmaktayız.Şimdi oluşturmuş olduğumuz C# Script dosyalarını gereken yerlere ekleyelim.İlk script dosyamız için boş bir nesne oluşturuyoruz ve ekliyoruz.Daha sonra Button nesnemizi seçiyoruz ve Inspector penceresinde bulunan On Click() bölümünde yer alan artı “+” butonuna basıyoruz.Sonra oluşan bölüme az önce oluşturduğumuz boş nesnemizi sürükleyip bırakıyoruz.
Boş bulunan fonksiyon yerine, listeden EkranDegistir() fonksiyonumuzu seçiyoruz.Artık butona tıkladığımızda ekran ayarlarımız değişkecektir.İkinci script dosyamızı ise, oyuncuların kullanacağı araç nesnelerinin üzerlerine sürükleyip bırakıyoruz.Daha sonra Inspector penceresinden, “Varsayılan Kontrol” bölümünü istediğimiz gibi ayarlıyoruz.Evet bu yazımında sonuna geldik.Bir sonraki yazıda görüşmek üzere…