Hepinize yine ve yeniden koca bir merhaba,

Yazılarımın giriş cümlesi o kadar klişe hale geldi ki her derste girişi nasıl değişik bir hale sokabilirim diye düşünmüyor değilim. Ama bir saniye; konumuz bu değil! Bu dersimizde Unity 4.6 sürümü ile gelen yeni UI (user-interface)(arayüz) sistemini inceleyeceğiz.

Twitter’da da bolca dile getirdiğim üzere yeni sistemi gerçekten çok sevdim. Sistemin güzel yanları daha az draw call harcaması, multi-touch desteklemesi, 3 boyutlu arayüz yapmayı mümkün kılması ve görsel olarak düzenlenebilmesi. Yani yeni sistemle birlikte artık arayüzü çizdirirken kod yazmanıza gerek yok.

Hazır mısınız? Harika! O halde derse başlıyorum.

NOT: Ders boyunca yapacağımız örnek uygulamaları içeren örnek projeyi indirmek için tıklayın: https://www.dropbox.com/s/b64v7wsvbpnth05/UI%20Ders.rar?dl=0

NOT2: Eğer dersi PDF formatında indirmek isterseniz tıklayın: https://www.dropbox.com/s/11jdtzk3tpkeu3l/Unity%20UI%20Sistemi.pdf?dl=0

UI sistemi çeşitli elemanlardan oluşmakta: canvas, panel, button, slider vb. Her bir eleman, adından da anlaşılacağı üzere farklı işlevselliğe sahip. Dersimize en temel UI elemanı ile başlayacağız: canvas!

Canvas

Canvas’ın iki mühim görevi vardır:

1- Diğer UI elemanlarını içinde barındırır. Yani diğer tüm arayüz elemanları canvas’ın child’ı olmak zorundadırlar.

2- UI sisteminin 2D mi yoksa 3D mi olacağını belirler. 2 boyutlu arayüz, şimdiye kadar kullandığımız OnGUI ve GUITexture‘ler ile aynıdır: arayüz oyun ekranının üzerine çizilir. 3 boyut desteği ise UI sistemi ile yeni gelen bir özellik ve bu özellik sayesinde oluşturduğunuz arayüz 3D uzayda bir konuma ve eğime sahip olabiliyor. Bu derste her iki boyutu da göreceğiz.

Button

Bu elemanın nolduğunu isminden de çıkarırsınız. Kendisi tıklanabilir (interaktif) bir buton rolünü üstlenir.

Bu elemanın özelliklerinden bahsetmeden önce birlikte bir canvas ve birkaç butondan oluşan basit bir arayüz oluşturmayı uygun buldum. Böylece yeni sistemle birlikte nasıl hiç kod yazmadan arayüz oluşturabildiğimizi görecek ve bazı önemli terimlerle tanışacaksınız: anchor ve pivot.

Unity’de boş bir sahne (scene) açın. Bu sahnede UI sistemini test edeceğiz.

Az önce UI sisteminin en temel biriminden bahsetmiştik: canvas. Butonlardan oluşan bir arayüz istiyoruz ancak bu butonlar bir canvas’ın child’ı olmak zorunda. Bu durumda canvas’ı iki şekilde oluşturmamız mümkün:

1- GameObject-UI-Canvas yolunu izleyerek elle oluşturabiliriz.

2- Direkt GameObject-UI-Button ile bir buton oluştururuz ve yeni bir canvas bizim için otomatik olarak oluşturulur.

Ben 2. yolu tercih edeceğim. GameObject-UI-Button yolunu izleyin. Hierarchy panelinizde bir canvas bir de button belirecek:

1

Canvas bizim için otomatik olarak oluşturuldu. Bu yetmezmiş gibi otomatik olarak bir de EventSystem oluşturuldu. EventSystem napar? Oluşturduğunuz arayüzün hem PC’de hem de mobil cihazlarda çalışabilmesini sağlar. Yani arayüzün mobil cihazlarda çalışması için ekstra bir efor sarf etmiyorsunuz, bu işi EventSystem vasıtasıyla Unity sizin için yapıyor.

Eğer Scene paneline bakacak olursanız devasa bir dikdörtgensel alan ve bu alanın içine yerleştirilmiş ufak bir buton göreceksiniz. İşte bu dikdörtgensel alan bizim canvas’ımız. Şu anda canvas 2D modunda, yani canvasın içinde oluşturduğumuz arayüz elemanları direkt oyun ekranının üzerine çizilecekler.

Peki arayüzü nasıl düzenleyeceğiz? Bunun en kolay yolu 2D moduna geçiş yapmak. 2D modunda Z ekseni kaybolur; sadece X ve Y eksenleri ile çalışırız. 2D moduna geçiş yapmak için Unity arayüzünün tepesinde yer alan 2D butonuna basmanız yeterli:

2

Şimdi canvas’ın içinde yer alan buton objesine tıklayarak onu seçin. Ardından klavyeden T tuşuna tıklayın veya araç çubuğundan Rect Handles aracını seçin:

2_2

Bu tool (araç) UI elemanlarını düzenlerken işe yarar. Neden ayrı bir tool kullanıyoruz derseniz çünkü UI elemanları Transform component’ine değil, Rect Transform component’ine sahiptirler ve bu component, Transform component’inin sahip olduğu değişkenlerden farklı değişkenlere de ev sahipliği yapar.

Butonu seçince karşımıza birkaç yeni gizmo çıkmış durumda:

3

Resimde de gördüğünüz üzere bu gizmo’lar pivot noktası ile anchor‘u temsil ediyor. Normalde butonun üzerinde Button yazıyordu ama pivot’un görünürlüğünü azalttığı için o yazıyı sildim.

Pivot

Açıkçası ben pivot’un bir faydasını görmedim. Pivot’un yerini bence hiç oynamayın. Pivot’un tek bir konuda çok işe yaradığını gördüm, o da arayüz elemanını döndürürken (rotate). UI elemanları pivotun etrafında döner ve pivotun konumunu değiştirirseniz objelerin dönme şekilleri de farklı olur.

Bir UI elemanını pivot etrafında döndürmek için, o elemanı saran dikdörtgensel hattın uçlarında yer alan mavi noktalardan herhangi birinin biraz dışına fare imlecini getirmeniz yeterli. Bu durumda fare imlecinin şekli değişecek ve sol mouse tuşuna basılı tuttuğunuz sürece o arayüz elemanı pivot etrafında dönecek:

4

Eğer pivotun yerini değiştirmediyseniz buton, kendi merkezi etrafında dönecektir. Ancak biz butonun kendi sol üst noktası etrafında dönmesini istiyoruz diyelim. O zaman yapmamız gereken şey pivotu tutup sürükleyerek butonun sol üst noktasına taşımak. Sonrasında butonu tekrar döndürün. Artık buton sol üst noktası etrafında dönecek:

5

Anchor

Pivot’u aradan elediğimize göre geldik en baba konuya: anchor. Arayüz elemanlarını yerleştirirken anchor’dan bolca faydalanacaksınız. Ekranın çözünürlüğü değiştikçe arayüz elemanlarının nasıl davranacaklarını belirleyen birkaç eleman var; bunlardan önemli bir tanesi de anchor.

Anchor’u, canvas üzerinde 4 üçgenin bir araya gelmesiyle oluşmuş bir ikon olarak görebilirsiniz (öncesinde buton objesini seçmeniz lazım). İşin ilginç yanı şu ki aslında her UI elemanının bir değil tam dört tane anchor’u vardır. O dört üçgenin her biri bir anchor’u temsil etmektedir. Eğer bu üçgenlerden herhangi birini tutup sürüklerseniz dört anchor birbirinden ayrılır:

6

Anchor’ların çok ama çok önemli bir özelliği var: her bir anchor aslında bağlı olduğu UI elemanının bir köşesiyle iletişim halindedir. Sıradaki cümleye lütfen dikkatinizi verin çünkü kritik nokta burası: Bir anchor ile o anchor’un bağlı olduğu köşe arasındaki uzaklık, ekranın çözünürlüğü ne kadar değişirse değişsin “daima” aynı kalacaktır. Mesela:

7

Bu örnekte iki farklı durumu göstermeye çalıştım. 1 numaralı durum bir önceki resimle aynı. Burada hangi anchor’un hangi köşeyle bağlantılı olduğuna (sol üst anchor butonun sol üst köşesiyle bağlantılı vs. vs.) ve anchor ile bağlantılı olduğu köşe arasındaki uzaklığa dikkat edin.

Ben bu butonun, genişliği daha az olan bir ekranda nasıl görüneceğini merak ettim ve Scene panelinin genişliğini epeyce azalttım. Anchor’lar da ekranla birlikte hareket etti (bu konuya değineceğim) ve 2 numaralı durumla karşılaştım. 2 numarada anchorlar birbirine daha bir yakınlaştı ama her iki durumda da anchor’lar ile köşeler arası uzaklıklar aynı kaldı. Harika!

Bu sistemi daha iyi anlamak için kendi canvas’ınızda biraz pratik yapmanızı şiddetle öneririm. Butonun anchorlarını birbirinden ayırıp istediğiniz noktalara dikin. Anchorlar ile bağlı oldukları köşeler arası uzaklığı dikkatlice gözlemleyin. Ardından Scene panelinin ebatlarıyla oynayın. Anchor’lar hareket edecek ve butonun da boyutu değişecek ama anchor’lar ile butonun köşeleri arasındaki uzaklık daima sabit kalacaktır.

Şimdi anchor’ların neye göre otomatik olarak konumlandırıldığını görelim. Bir önceki resimdeki 1 ve 2 numaralı durumların farkı sol ve sağdaki anchor’ların 2 numarada birbirine daha yakın olmasıydı. Bunun sebebi de ikinci durumda ekranın genişliğinin daha küçük olmasıydı.

Anchor’lar konumlandırılırken % sistemi ile hareket edilmekte. Bunu bir örnek üzerinden anlatacağım:

8

Unity’de anchor’ları konumlandırırken ekranda, resimde görüldüğü gibi çeşitli % ifadeler belirir. Bunlar, ilgili anchor’un ekranın kenarlarından ne kadar uzakta olacağını belirlemektedir.

Örneğin sol alttaki anchor’u ele alalım. Bu anchor her zaman için canvas’ın solundan, canvas’ın genişliğinin %17’si kadar uzakta yer alacak. Benzer şekilde, canvas’ın alt noktasından ise canvas’ın yüksekliğinin %25’i kadar uzakta yer alacak (yani 1/4’ü kadar). Biz ekranın (yani dolaylı olarak canvas’ın) yüksekliğini ne kadar değiştirirsek değiştirelim anchor’daki bu oranlar asla değişmeyecektir. Ekranın çözünürlüğü 100×100 iken sol alt anchor’un canvas’ın sol alt köşesine uzaklığı (17,25) pixel olurken ekranın çözünürlüğü 200×60 iken (34,15) pixel olacaktır. Umarım konsept anlaşılmıştır.

O halde anchor’larla ilgili bilmemiz gereken iki önemli bilgi var:

  • Bir anchor ile o anchor’un bağlı olduğu köşe arasındaki uzaklık daima aynıdır. Yani siz arayüzü tasarlarken bu uzaklık (10,20) pixel ise ekranın çözünürlüğünü ne kadar ellerseniz elleyin; uzaklık daima (10,20) pixel olarak kalacaktır.
  • Bir anchor’un canvas’ın kenarlarına olan % cinsinden uzaklığı, ekranın çözünürlüğünü ne kadar ellerseniz elleyin daima aynı kalır.

Sıra geldi bu öğrendiğimiz bilgileri hazır sıcakken pratiğe dökmeye. Mesela canvas’ın içindeki butonun sol kenarıyla canvas’ın sol kenarı arasındaki uzaklığın daima 50 pixel olmasını istiyoruz diyelim. Benzer şekilde, sağ kenarlar arası mesafe ise daima 70 pixel olsun istiyoruz diyelim. Burada referans noktası olarak canvas’ın sağ ve sol kenarlarını alıyoruz. O halde ilk işimiz, butonun sol anchor’larını canvas’ın sol kenarına dayamak, sağ anchor’larını ise canvas’ın sağ kenarına dayamak olmalı. Yani şu şekilde:

9

Artık sol anchor’lar (canvas’ın sol kenarı) ile butonun sol köşeleri arası uzaklık sabit hale geldi. Biz bu uzaklığın sol tarafta 50 pixel, sağ tarafta 70 pixel olmasını istiyoruz. Burada iki farklı yol izleyebiliriz:

A) Butonu Elle Konumlandırmak

Yapmamız gereken şey, butonun sol kenarına fare imlecini getirmek ve sol mouse tuşu basılıyken butonun sol noktasını çekiştirmek. Bu işlemi, butonun sol kenarı ile canvas’ın sol kenarı arası uzaklık 50 pixel olana kadar yapmalıyız:

10

Farkedeceğiniz üzere bu metot biraz zahmetli çünkü tam istediğiniz uzaklığı elde etmek için ince ayar yapmanız gerekebiliyor. Ancak elbette ki imkansız değil.

B) Butonu Rect Transform Vasıtasıyla Konumlandırmak

Bu metot öncekine nazaran çok daha kolay. Nasıl mı? Butonu seçiyorsunuz ve Rect Transform‘daki “Left” değerini 50 yapıyorsunuz:

11

İşte bu kadar! “Right“ı da 70 yaptığınız zaman artık sağ anchor’lar (canvas’ın sağ kenarı) ile butonun sağ köşeleri arası uzaklık 70 pixel olacak. Buradaki “Top” değerinin üst anchor’lar ile butonun üst köşeleri arası dikey uzaklık, “Bottom“un ise alt anchor’lar ile butonun alt köşeleri arası dikey uzaklık olduğunu kendiniz anlamışsınızdır herhalde.

Artık yaptığımız sistemi test edebiliriz. Bunu yapmanın kısa yolu Hierarchy‘den Button objesini seçmek ve ardından Canvas‘ın kenarlarından tutarak canvas’ı yeniden boyutlandırmak. Canvas’ı yeniden boyutlandırma işlemi sadece önizleme (preview) amaçlıdır ve elinizi sol mouse tuşundan çektiğiniz anda canvas eski haline dönecektir. Eğer herşeyi düzgün yapmışsanız canvas’ın genişliğini değiştirdiğinizde butonun genişliği artacak/azalacak ama butonla canvas’ın kenarları arası mesafe asla değişmeyecektir.

Burada bilmeniz gereken önemli bir nokta var: eğer canvas’ın genişliğini 120 pixelden daha küçük yaparsanız buton kırmızı bir çarpı işaretine dönüşecektir ve artık görünmeyecektir; çünkü butonun kenarlara olan uzaklığı 50+70=120 pixel. Bu da demek oluyor ki eğer oyunu 120 pixelden daha ufak genişliğe sahip bir ekranda oynarsak buton ekranda gözükmeyecek. Böyle ufak bir ekran genişliği yoktur elbet; o yüzden şu anki durumda bir sıkıntı yok ama siz butonun kenarlara olan uzaklığını belirlerken bu bilgiyi unutmayın zira uzaklığı elle artırdıkça o butonun ekranda görünmesi için gerekli minimum ekran genişliği de artacaktır.

Peki şimdi şöyle birşey yapalım: ekranda üç buton olsun. Bu butonların ekranın sol ve sağ kenarlarına olan uzaklığı 50’şer pixel olsun. Butonlar alt alta dizili olsun ve iki buton arası dikey uzaklık 60 pixel olsun. Bu üç butonun yükseklikleri ise birbirine eşit olsun. Bunu kendiniz yapmaya çalışın. En son elde ettiğiniz sonucu benimkiyle kıyaslayın (sonuç benimkiyle aynı olacak diye birşey yok; bu verdiğim tanıma uyan farklı farklı arayüzler oluşturmak mümkün):

12

Eğer elde ettiğiniz sonuç benimkine az biraz benziyorsa tebrikler! İşin güzel yanı, burada öğrendiğimiz konumlandırma işlemi tüm UI elemanlarında ortak olan birşey. Yani butonları, panelleri, slider’ları, image’ları vb. hep bu anchor dediğimiz şeyi kullanarak konumlandırıyorsunuz; prosedür hepsinde aynı.

ÖNEMLİ BİLGİ: Buraya kadar kafanız karışmasın diye sizden özellikle sakındığım bir bilgi vardı: bir UI elemanının anchor’larını sadece parent objesinin sınırları içerisinde dolaştırabilirsiniz. Şu ana kadar hep butonlarla işlem yaptık ve butonlarımız da direkt olarak canvas’ın child objeleriydi (bir başka deyişle canvas, butonların parent objesiydi). Bu yüzden anchor’ları canvas’ın sınırları dahilinde istediğimiz gibi dolaştırabiliyorduk. Ama mesela butonun child objesi olan Text‘i ele alalım (her buton varsayılan olarak bir Text child objesi ile oluşturulur). Eğer Hierarchy‘den bir butonun Text isimli child’ını seçecek olursanız göreceksiniz ki bu Text’in anchor’ları sadece butonun içerisinde hareket edebiliyor, butonun dışına çıkamıyor (tıpkı butonun anchor’larının canvas’ın dışına çıkamaması gibi). Buradan anlayacağımız şey şu: bir UI elemanını konumlandırırken anchor’larımızın referans düzlemi parent objenin kendisidir.

Beraber bir örnek daha yapalım. Bu sefer elimizde bir buton olsun ve bu butonun ekranın üst kenarına olan uzaklığı 100 pixel olsun. Butonun genişliği 350 pixel olsun ve bu değer sabit olsun; yani canvas’ın (ekranın) genişliği değişse de butonun genişliği değişmesin. Butonun alt kenarının ekranın üst kenarına uzaklığı ise daima ekranın yüksekliğinin 1/4’ü kadar olsun. Referans resim ve cevap için alttaki resme bakabilirsiniz:

13

NOT: Pivot’un konumuna göre “Pos X“in değeri sizde farklı olabilir.

Butona Basınca Yapılacakların Ayarlanması

Yeni UI sisteminde interaktif buton oluşturmak eski sisteme nazaran biraz değişmiş. Eskiden GUITexture‘lerde OnMouseDown() fonksiyonunu kullanırdık ama artık daha farklı bir yol izliyoruz.

Canvas’ta bir tane buton oluşturun. Bu butona tıklayınca konsola “Merhaba Dünya” yazdırmak istiyoruz diyelim. Bunun için bir scripte ihtiyacımız olacak. Bu örnekte Javascript kullanacağım ama siz isterseniz C#‘ta kullanabilirsiniz.

MerhabaScript.js” adında yeni bir Javascript oluşturup içeriğini şöyle düzenleyin:

#pragma strict

public function Merhaba()
{
	Debug.Log( "Merhaba Dünya" );
}

Bu scripti istediğiniz objeye verin (ben Main Camera‘ya vereceğim). Şimdi buton objesini seçin. Inspector‘da “On Click()” diye bir kısım var. Bu (şu anda boş olan) bir listedir. Butona tıklandığı zaman bu listede yer alan fonksiyonlar otomatik olarak çağrılır. Biz Main Camera’daki MerhabaScript script’inin Merhaba() fonksiyonunu çağırmak istiyoruz. Bunun için oradaki + işaretine tıklayın. Obje olarak Main Camera’yı seçin ve fonksiyon olarak MerhabaScript-Merhaba() yolunu izleyin:

14

Şimdi oyunu çalıştırıp butona tıklayın. Konsola “Merhaba Dünya” yazılması lazım. Gördüğünüz gibi butona tıkladığımız zaman sahnedeki istediğimiz bir objenin istediğimiz bir fonksiyonunu çağırabiliyoruz. Yalnız çağrılabilecek fonksiyonların türleri konusunda bazı kısıtlamalar var. Bunları şöyle sıralayabiliriz:

  • Fonksiyon public olmak zorunda.
  • Fonksiyon 0 ya da 1 parametre alabilir.
  • Fonksiyonun parametresinin türü sadece int, float, boolean, String veya Object (mesela Transform veya GameObject) olabilir.

Bizim Merhaba fonksiyonumuz public ve hiç parametre almıyor. MerhabaScript’i açın ve içine şu fonksiyonu ekleyin:

public function Merhaba2(yazi:String)
{
	Debug.Log( yazi );
}

Bu fonksiyon public, 1 parametre alıyor ve parametresinin türü String. Yani tüm şartlara uyuyoruz. Şimdi buton objesini tekrar seçin ve “On Click()” listesine bir de “MerhabaScript.Merhaba2()”yi ekleyin:

15

Görüldüğü üzere Merhaba2’nin altında boş bir metin kutusu belirdi. İşte buraya Merhaba2 fonksiyonunun parametre olarak aldığı yazi‘nın değerini girebiliriz. Oraya TEST yazın ve oyunu çalıştırın. Butona tıkladığınızda konsola hem “Merhaba Dünya” hem de “TEST” yazılacaktır.

UI Elemanlarını Konumlandırmakla İlgili Ufak Bir İpucu

Shift tuşu! Bu tuş çok işinize yarayabilir.

Objeyi bir yerden bir yere taşıyorsanız Shift’e basılı tuttuğunuz zaman obje ya yatay eksende ya da dikey eksende hareket eder, diğer eksendeki konumu değişmez.

UI elemanının köşelerinden tutup onu boyutlandırırken Shift’e basılı tutarsanız UI elemanının genişlik/yükseklik oranı bozulmaz, obje her iki eksende de bu oranı bozmayacak şekilde boyutlanır.

Button (Script)

Buton objesini seçtiğiniz zaman Inspector‘unda “Button (Script)” adında bir component‘in yer aldığını farketmişsinizdir. Buradaki değerlerin üzerinden hızlıca geçeceğim.

Interactable: Butonun tıklanabilir olup olmadığını belirlemeye yarar. Bu seçeneği kapatırsanız butonun “On Click()” listesi çalışmaz.

Transition: Butona geçiş (transition) animasyonları vermeye yarar. Peki bu geçişler ne zaman olur? Örneğin butonun üzerine fare imlecini getirdiğinizde “Normal“den “Highlighted“a geçiş yapılır. Butona tıkladığınızda “Highlighted“dan “Pressed“e geçiş yapılır. Eğer buton Interactable değilse daima “Disabled” olarak kalır.

Eğer TransitionColor Tint” ise geçişler sırasında butonun rengi bir nebze değişir. Bu renkleri Inspector‘dan ayarlayabilirsiniz. Buradaki “Fade Duration” değeri renkler arası geçişin kaç saniyede gerçekleşeceğini belirler.

Transition‘ı “Sprite Swap” yaparsanız her transition’da butonun sprite‘sinin değişmesini sağlarsınız. Sprite ne derseniz Texture2D’nin UI sistemindeki versiyonu diyebilirim.

Transition‘ı “Animation” yaparsanız butona Animator component‘i vasıtasıyla istediğiniz kadar detaylı bir animasyon verebilirsiniz. Örneğin butonun üzerine mouse ile gelince butonun boyutu biraz artsın, butona tıklayınca butonun rengi kırmızı olsun istiyoruz diyelim. Bunu sağlamak için önce “Auto Generate Animation” butonuna tıklayın:

16

Controller‘a isim olarak “AnimasyonTest” verin ve asset’i istediğiniz yere kaydedin. Şimdi buton objesi seçiliyken Window-Animation yoluyla Animation penceresini açın. Sol üstteki Normal‘i Highlighted ile değiştirin (Highlighted transition’ı, butonun üzerine mouse imlecini getirdiğimiz zaman gerçekleşir):

17

Highlighted‘ın sol üstünde yer alan kırmızı daire şeklindeki butona bir kere tıklayın. Editörün tepesindeki Play ve Pause butonları kırmızı renge bürünecektir: şu anda kayıt modundayız. Bu haldeyken buton üzerinde yaptığımız değişiklikler animasyona yazılır.

Kayıt modundayken butonun Rect Transform‘undaki Scale X ve Y değerlerini 1.25 yapın. Sonrasında Play tuşuna basarak sistemi test edin. Fare butonun üzerine gelince buton büyüyecek.

Şimdi Animation‘a geri dönün ve Highlighted‘ı Pressed ile değiştirin. Yine kırmızı daireye bir kere tıklayın ve bu sefer butonun Image component‘indeki Color değerini kırmızı yapın:

18

Sistemi tekrar test edin. Butona basınca buton kırmızı renge bürünecek.

Bu bölümde elimden geldiğince butonu anlatmaya çalıştım. Üzerinden geçmediğim kısımları Unity dokümantasyonundan, yazılı ve(ya) video derslerden kendiniz tamamlamaya çalışın. Benzer şekilde, sonraki bölümlerde de ilgili UI elemanlarının sadece temel özelliklerine değineceğim.

Text

Sıradaki UI elemanımız Text. Bunu seçmemin sebebi her butonun halihazırda bir Text ile oluşması. Biz zaten butonu gördüğümüze göre o halde Text’in sırası geldi de geçiyor.

Text dediğimiz eleman ekrana bir yazı yazdırmaya yarar. Butonlar varsayılan olarak “Button” yazısıyla gelirler. Bu yazıyı istediğiniz gibi değiştirmek için butonun child objesi olan Text‘i seçin ve Inspector‘da “Text (Script)” component’i altındaki Text değerini değiştirin. Dikkat edin: Text’in içine birden çok satırdan oluşan bir yazı da girebilirsiniz.

Text (Script)“in sahip olduğu önemli değerler şunlar:

Horizontal Overflow: Değeri Wrap olursa yazının butona sığmayan kısmı bir alt satıra yazılır. Değeri Overflow olursa yazı butonun dışına taşabilir.

Vertical Overflow: Değeri Truncate olursa yazı butonun dışına taşamaz, Overflow olursa taşabilir.

Best Fit: Eğer işaretlenirse yazının boyutu, içinde bulunduğu dikdörtgensel alana tam sığacak şekilde otomatik olarak ayarlanır. Ancak siz yine de bu otomatik boyutlandırmaya bir alt limit (Min Size) ve üst limit (Max Size) belirleyebilirsiniz.

Buradaki diğer özellikler çok bariz olduğu için açıklama zahmetine girmiyorum.

Text ile ilgili güzel bir bilgi daha paylaşmak istiyorum: Text vasıtasıyla oluşturduğunuz yazılara efektler vermeniz mümkün. Şu anda üç efekt var: Shadow (gölge), Outline (dış hat) ve “Position As UV1” (nolduğunu bilmiyorum). Örneğin bir yazıya gölge efekti vermek istiyorsunuz diyelim. Yapmanız gereken o Text objesini seçmek ve Component-UI-Effects-Shadow yolunu izlemek. Artık o yazının bir gölgesi var. “Shadow (Script)” component’indeki ayarlarla oynayarak gölgeyi istediğiniz gibi renklendirebilir ve konumlandırabilirsiniz. Gölge uygulanmış örnek bir Text:

18_2

Panel

Bu UI elemanı benim anladığım kadarıyla ekrana bir kutucuk çizdirmeye yarıyor. Varsayılan olarak bu kutucuk tüm ekranı kaplıyor ancak kutucuğu siz istediğiniz gibi konumlandırabilirsiniz. Daha da bahsedecek bir “özellik” bulamadım.

Arayüze UI Elemanlarının Çizdirilme Sırasını Belirlemek

Bu bilgi kırıntısını bir yere not edin çünkü çok işinize yarayabilir. Arayüz elemanlarının canvas üzerinde çizdirilme sırasını elle belirleyebiliyorsunuz. Örneğin arayüzün arkaplanına bir panel koyacaksınız diyelim. Ama o da ne! Panel butonların üzerini kapatıyor. Biz panelin butonlardan önce çizilmesini, böylece butonların arkasında kalmasını istiyoruz. Bunu yapmanın yolu çok basit: paneli Hierarchy‘de buton objesinin yukarısına taşıyın:

19

Canvas içerisinde yer alan objeler yukarıdan aşağıya doğru çizilir. Biz Panel’i başa alarak önce onun çizilmesini sağladık. Böylece sonradan çizilen Button, panelin üzerinde kalıyor ve sorunumuz çözülmüş oluyor.

Image (ve RawImage)

Image, ekrana bir resim (Sprite) çizdirmeye yarar. Bu objenin en önemli değişkeni tabi ki “Image (Script)” component’i içinde yer alan “Source Image” kısmı. Buraya çizdirmek istediğiniz sprite’yi sürüklemeniz yeterli.

Image objesinin bir de RawImage diye farklı versiyonu mevcut. RawImage ise ekrana bir Sprite değil Texture çizdirmeye yarar. Ancak burada yer alan “UV Rect” değerleri neyi temsil ediyor bilmiyorum.

Toggle

Kullanıcı sözleşmelerinin altında, sözleşmeyi onayladığınıza dair bir onay kutucuğu olur. İşte o kutucuk bir toggle‘dır. Toggle dediğimiz onay kutucuğu ya işaretli olur ya da olmaz (bir boolean‘ın değerini değiştirmek için mükemmel tercih).

Yeni bir sahne açın ve içinde GameObject-UI-Toggle yolunu izleyerek bir Toggle oluşturun. Hierarchy‘de Toggle’ın üç child objeye sahip olduğunu göreceksiniz: Background, Checkmark ve Label. Buradaki Background, onay kutucuğunun arkaplanını çizdirmeye yararken Checkmark da kutucuğa konulan tik işaretini çizdirmeye yarar. Label ise Toggle’ın sahip olduğu Text‘i değiştirmeye yarar. Bizi asıl ilgilendiren Toggle objesindeki “Toggle (Script)” component’i.

Bu component’te yer alan önemli değişkenlerden bahsedecek olursak:

Is On: Oyunun başında kutucuğun işaretli olup olmayacağını belirtir.

Toggle Transition: Çok gereksiz bir özellik, bırakın Fade olarak kalsın.

Group: Bazen karşınızda birden çok işaretlenebilir kutucuk olur ama bunlardan aynı anda sadece biri seçili olabilir (örneğin cinsiyeti soran işaret kutucukları). İşte böyle bir durumda, aralarından sadece birinin işaretlenebildiği işaret kutucuklarını gruplandırabiliyoruz. Bu değişkene değer vermeyi birazdan göreceğiz.

On Value Changed(Boolean): Nasıl Button‘da “On Click()” vardıysa bunda da “On Value Changed(Boolean)” var. Onay kutucuğuna işaret koyduğumuz/var olan işareti kaldırdığımız zaman bu listede yer alan fonksiyonlar çağrılır.

Toggle’ı anlatmak için aklıma gelen yöntem şöyle: birlikte tek soruluk bir test uygulaması yapacağız. Soru “Hangi ışıkta geçilir?” olacak ve şıklar da (tahmin edeceğiniz üzere) kırmızı, sarı ve yeşil olacak. Bu Toggle’lardan aynı anda sadece biri işaretlenebilecek. Doğru seçeneği seçtiğimizde (acaba hangisi??) konsola “KAZANDIN!” mesajı yazdırılacak.

O halde boş bir sahne açın ve içinde 1 tane Text, 3 tane de Toggle objesi oluşturun. Text’i en tepeye alın ve Toggle’ları da onun altına istediğiniz gibi dizin. Toggle’ların isimlerini “KirmiziToggle“, “SariToggle” ve “YesilToggle” olarak değiştirin (ki hangi toggle’ın kimi temsil ettiğini rahatça anlayabilelim).

Text‘i seçin ve değerini “Hangi ışıkta geçilir?” olarak değiştirin. Ardından KirmiziToggle‘ın “Label” isimli child objesini seçin ve oradaki Text‘i “Kırmızı” yapın. Eğer biraz daha görsellik katmak istiyorum derseniz de bu sefer KirmiziToggle’ın Background child objesini seçin ve oradaki “Color” değerini kırmızı yapın. Böylece işaret kutucuğu kırmızı renkle boyanacak. Çok havalı! Son olarak Toggle’ın kendisini seçin ve “Is On” değerini false yapın.

Diğer Toggle’lar için de aynı işlemi uygulayın. Bende bu adım sonrasında arayüz şöyle duruyordu:

20

Bu Kırmızı, Sarı ve Yeşil cevaplarından aynı anda maksimum 1 tanesinin seçili olabilmesini istiyoruz. O halde Toggle‘ın “Group” değişkeninden faydalanacağız. Ama öncesinde bir “Toggle Group” oluşturmamız lazım. “Toggle Group” component’ini Component-UI-Toggle Group yolunu izleyerek istediğiniz bir objeye ekleyin. Ben KirmiziToggle objesine ekledim.

Toggle Group‘un özel bir değişkeni var: “Allow Switch Off“. Bu değişkenin değeri true olursa, o grupta aynı anda hiçbir onay kutucuğunun işaretli olmaması mümkün olur. Değişkenin değeri false olursa bu sefer gruptaki işaret kutucuklarından birisi her zaman işaretli olmak zorunda olur. Bizde öyle bir zorunluluk olmadığı için bu değişkeni true yapın:

21

Şimdi KirmiziToggle, SariToggle ve YesilToggle objelerini tek tek seçin ve her birinin Group değişkenine değer olarak “Toggle Group” component’ine sahip objeyi (KirmiziToggle) verin. Oyunu çalıştırdığınızda 3 kutucuk arasından aynı anda maksimum 1 tanesinin işaretlenebildiğini göreceksiniz.

Sıra geldi doğru cevabı bilince ödülümüzü almaya. “KpssScript.js” adında yeni bir Javascript oluşturun. YesilToggle‘ı işaretlediğimiz zaman bu scriptteki bir fonksiyonu çağırmak, çağrılan o fonksiyon vasıtasıyla da konsola “KAZANDIN!” yazdırmak istiyoruz. O halde scriptin içeriğini şöyle düzenleyelim:

#pragma strict

function DogruCevap( isaretlendiMi : boolean )
{
	if( isaretlendiMi )
		Debug.Log( "KAZANDIN!" );
}

Scripti herhangi bir objeye (Main Camera) verin. Sonrasında YesilToggle‘ı seçip “On Value Changed(Boolean)” listesine Main Camera’daki KpssScript.DogruCevap fonksiyonunu ekleyin. Yalnız burada çok ince bir detay var o da şu ki bu listede iki tane DogruCevap fonksiyonu var:

22

Bu iki DogruCevap arasından üsttekini (“Dynamic bool” altında yer alanı) seçmelisiniz. Üsttekiyle alttakinin ne farkı var derseniz; üsttekinde DogruCevap fonksiyonuna otomatik olarak onay kutucuğunun sahip olduğu değer gönderilirken alttakinde ise DogruCevap fonksiyonuna yollanacak boolean parametresinin değeri elle girilir. Biz, fonksiyona onay kutucuğunun sahip olduğu değerin gitmesini istiyor ve bunun için üstteki DogruCevap’ı seçiyoruz.

Herşeyi düzgün yaptıysanız şu anda oyunu çalıştırıp doğru cevabı bildiğinizde konsola tebrik yazısı yazdırılmalı. Eğer birşey olmuyorsa örnek projeyi kontrol etmenizi öneririm.

Input Field

Bu UI elemanı, adından da anlaşılacağı üzere kullanıcıdan bir String input almaya yarar. Bu input kullanıcının ismi de olabilir, şifresi de olabilir, e-mail adresi de olabilir, o da olabilir bu da olabilir; aklınıza ne gelirse…

Bu kısımda da örnek bir uygulama yapacağız. Ekranımızda iki Input Field yer alacak ve soldakine yazdığımız yazının tersi, sağdakine otomatik olarak yazdırılacak. Yani cümleyi tersten yazdıracağız.

Yeni bir scene oluşturup ekrana iki tane Input Field ekleyin. Bu Input Field’ları alt alta koyun. Üsttekinin arkaplan rengini açık yeşil, alttakinin arkaplan rengini ise açık sarı yapın (hangi Color değerini ellemeniz gerektiğini kendiniz keşfedin). Şimdi birlikte InputField’ın child objelerine bakalım:

Placeholder: Eğer ki input field’ın içi boşsa, input field’a birşeyler karalayana kadar input field’da bu Text görünür.

Text: Input field’a birşeyler karaladığımız anda artık input field’da bu text görünür.

Üstteki input field’ın placeholder’ının yazısını “Birşeyler yazın…” olarak, alttakinin yazısını ise “Yazılan cümlenin tersi…” olarak değiştirin:

23

Gelelim “Input Field (Script)” component’indeki önemli değişkenlere:

Text: Oyunun başında input field’da yazılı olan değeri değiştirmeye yarar. Varsayılan olarak burası boştur.

Character Limit: Girilen input’un maksimum kaç karakter uzunluğunda olabileceğini belirler.

Content Type: Girilen input’un türünü belirler. Ona göre o input field her karakteri kabul etmez. Önemli content type’lar şunlar:

  • Standard: Her türlü karakter kabul edilir.
  • Integer Number: Sadece rakamlar kabul edilir.
  • Decimal Number: Rakamlar ve nokta işareti kabul edilir (küsürlü sayılar girmek için)
  • Password: Her karakter kabul edilir. Input’taki karakterler * işareti ile temsil edilir.
  • Pin: Sadece rakamlar kabul edilir. Input’taki karakterler * işareti ile temsil edilir.

Line Type: Eğer değeri “Single Line” olursa input field tek satırlık String kabul eder, “Multi Line Newline” olursa input field birden çok satırlık String de kabul eder. Yalnız birden çok satırı rahatça göstermek için input field’ın yüksekliğini elle artırmanız gerekebilir.

Caret Blink Rate: Input girerken yanıp sönen o işaretçiğin (tam olarak Türkçe’si ne bilmiyorum) yanıp sönme hızını belirlemeye yarar.

Selection Color: Input Field’dan bir yazı seçtiğimizde, seçili yazının boyanacağı rengi belirler.

On Value Change(String): Input field’a yeni bir karakter girdiğimizde/varolan bir karakteri sildiğimizde bu listedeki fonksiyonlar çağrılır.

End Edit(String): Input field’a gireceklerimizi girip Enter’a bastığımızda veya arayüzdeki boş bir yere tıklayarak işimizi bitirdiğimizde (artık o input field’a odaklanmadığımızda) bu listedeki fonksiyonlar çağrılır.

İsterseniz önce bir “End Edit(String)“i test edelim. “TerstenScript.js” adında yeni bir Javascript oluşturup içeriğini güncelleyin:

#pragma strict

function InputYazdir( yazi : String )
{
	Debug.Log( yazi );
}

Sonrasında bu scripti Main Camera‘ya verin ve üstteki Input Field‘ın “End Edit(String)” listesine TerstenScript.InputYazdir fonksiyonunu ekleyin (“Dynamic string” altında yer alan fonksiyonu seçeceksiniz, en alttakini değil!).

Oyunu çalıştırın. Üstteki kutucuğa birşeyler yazıp Enter’a bastığınızda veya mouse ile başka bir yere tıkladığınızda konsola, input field’daki yazı yazdırılacak.

Gelelim asıl kısma: üstteki input field’a her düzenleme yaptığımızda alttaki input field’ın güncellenmesini istiyoruz. Bunun için alttaki input field’ı bir değişkende tutmalı, üstteki input field’ın değeri değiştikçe alttakinin Text değerini script vasıtasıyla güncellemeliyiz.

TerstenScripts.js“yi şu şekilde güncelleyin:

#pragma strict

import UnityEngine.UI;

public var alttakiInputField : InputField;

function AlttakiniGuncelle( usttekiInput : String )
{
	var alttakiOutput : String = "";
	
	for( var i = usttekiInput.Length - 1; i >= 0; i-- )
	{
		alttakiOutput += usttekiInput[i];
	}
	
	alttakiInputField.text = alttakiOutput;
}

function InputYazdir( yazi : String )
{
	Debug.Log( yazi );
}

InputField türünde public bir değişkenimiz var: alttakiInputField. Unity’nin yeni UI sistemiyle ilgili kod yazarken scriptimizin başına “import UnityEngine.UI;” komutunu eklemek zorundayız çünkü UI class’ları “UnityEngine.UI” paketinin (package) içinde yer alır.

Scripte AlttakiniGuncelle adında yeni bir fonksiyon ekledik. Bu fonksiyon bir parametre alıyor, onu ters çevirip alttakiInputField‘ın text‘ine değer olarak veriyor.

Şimdi Main Camera‘ya gelin ve “Tersten Script” component’inin “Alttaki Input Field” değişkenine değer olarak alttaki input field’ı verin. Sonrasında üstteki input field’ı seçin ve “On Value Change(String)” listesine TerstenScript.AlttakiniGuncelle fonksiyonunu ekleyin. Ardından sistemi test edin. İşte örnek bir resim:

24

Slider

Bu eleman ekrana bir slider çizdirmeye yarar elbette ki. Slider’ın ne olduğunu hatırlamıyorsanız sahnede bir Slider oluşturun, hemen anlayacaksınız.

Slider ile ilgili iki örnek uygulama yapacağız. İlkinde ekranda bir slider bir de text olacak ve bu slider’ın değerini değiştirdikçe yazı büyüyüp küçülecek.

O halde hemen yeni bir scene oluşturup içine bir slider bir de text ekleyin. Text’i slider’ın üzerine taşıyın ve değer olarak istediğiniz yazıyı verin:

25

Kodlama yapmaya başlamadan önce “Slider (Script)” component’ini inceleyelim:

Min Value: Slider’ın döndürebileceği minimum değeri belirler.

Max Value: Slider’ın döndürebileceği maksimum değeri belirler.

Direction: Slider’ın yönünü belirler:

  • Left To Right: Slider soldayken minimum, sağdayken maksimum değer döndürülür.
  • Right To Left: Slider soldayken maksimum, sağdayken minimum değer döndürülür.
  • Top To Bottom: Slider tepedeyken minimum, dipteyken maksimum değer döndürülür.
  • Bottom To Top: Slider tepedeyken maksimum, dipteyken minimum değer döndürülür.

Whole Numbers: İşaretlenirse, slider değer olarak sadece [Min Value, Max Value] aralığındaki tamsayıları döndürebilir.

Value: Oyun başladığında slider’ın sahip olacağı değeri belirler.

On Value Changed(Single): Slider’ın değerini değiştirdiğimiz zaman bu listedeki fonksiyonlar çağrılır.

Şimdi “SliderTest.js” adında yeni bir Javascript oluşturun:

#pragma strict

import UnityEngine.UI;

public var yazi : Text;

function YaziyiBoyutlandir( boyut : float )
{
	Debug.Log( boyut );
	
	yazi.rectTransform.localScale = new Vector3( boyut, boyut, boyut );
}

YaziyiBoyutlandir fonksiyonu bir float parametre alıyor ve yazının “Rect Transform” component’inin “Scale” değerini bu parametreyi kullanarak değiştiriyor (Scale‘i script vasıtasıyla değiştirirken localScale değişkeni kullanılır).

Scripti Main Camera‘ya verin. Yazi‘ya değer olarak Text objesini verin. Sonra slider’ın “On Value Changed(Single)” listesine SliderTest.YaziyiBoyutlandir fonksiyonunu ekleyip oyunu çalıştırın. Yazının slider ile boyutlanması lazım. Eğer olmuyorsa örnek projeyi kontrol edebilirsiniz.

Gelelim ikinci örnek uygulamaya. Bu örnekte bir health bar (sağlık barı) simüle edeceğiz. Ekranda iki de buton olacak: sağlık butonu ve hasar butonu. Sağlık butonu sağlık barını doldururken hasar butonu sağlığın bir kısmını götürecek.

Yeni bir sahne oluşturup içine bir slider, iki de buton ekleyin. Slider‘ın Direction‘ını “Bottom To Top” yapın. İki butonu slider’ın yanına dizin:

26

Bu örnekteki slider’ı biraz kişiselleştirmemiz lazım. Örneğin slider’ın elle değiştirilmesini istemiyoruz. Bu durumda slider’ın ucundaki daireye ihtiyacımız yok. Neyse ki onu direkt olarak silmemiz mümkün ve bu bir sorun da teşkil etmiyor. Slider‘ın “Handle Slide Area” isimli child objesini seçin ve silin. Güle güle daire!

Daireyi silince arkada gri bir arkaplan belirdi. Biz bunu da istemiyoruz. Slider‘ın “Background” isimli child objesini de silin!

Eğer oyunu açıp test ederseniz, slider’ın herhangi bir yerine tıklayınca onun değerini hâlâ değiştirebildiğimizi göreceksiniz. Biz buna kesin bir şekilde engel olmalıyız. Slider’ın değerini sadece kod yardımıyla değiştirebilmeliyiz. Bunu yapmak için Slider objesinin “Interactable” değişkenini false yapın. Artık slider’ın değerini oyun sırasında elle değiştirmek kesinlikle mümkün değil.

Slider (Script)” component’inde bir uyarı mesajı görmüşsünüzdür:

27

Hata mesajı diyor ki slider’a renk değişimi efekti (transition) uygulayabilmek için, bu efektin uygulanacağı bir hedef obje seçmeliyiz. Ama bu slider etkileşime geçilen bir slider olmadığı için biz zaten herhangi bir transition efekti istemiyoruz. Bu uyarıdan kurtulmak için “Transition“ı “None” yapmanız yeterli.

Yapacağımız bir sonraki değişiklik sağlık barının değer aralığını değiştirmek. Benim sağlık barım [0,100] aralığında bir tamsayı değeri alacak. Bunun için slider’ın “Min Value“sini 0, “Max Value“sini 100 yapıyor ve “Whole Numbers” kutucuğunu işaretliyorum. Sonrasında değeri 1 olan “Value“yi 100 yapıyorum. Oyunun başında sağlığımız dolu olacak.

Son olarak sağlık barının rengini yeşil yapalım. Bunun için slider’ın “Fill” isimli child objesinin rengini değiştirmeniz yeterli:

28

Gelelim kod kısmına. “SaglikBari.js” adında yeni bir Javascript oluşturun:

#pragma strict

import UnityEngine.UI;

public var saglikBari : Slider;

function HasarVer()
{
	saglikBari.value -= 10;
	Debug.Log( saglikBari.value );
	
	if( saglikBari.value <= 0 )
		Debug.Log( "Karakter öldü" );
}

function Wololo()
{
	// AOE2 oynamayanlar bilmez : D
	saglikBari.value += 10;
	Debug.Log( saglikBari.value );
}

Bu scriptte “saglikBari” adında public bir değişkenimiz var; değişkenin türü Slider. Bu değişkende sağlık barını depolayacağız.

Scriptin iki fonksiyonu var:

  • HasarVer(): sağlığı 10 azaltıyor ve eğer sağlık 0’a inmişse konsola, öldüğümüze dair bir mesaj yazdırıyor.
  • Wololo(): sağlığı 10 artırıyor.

Yapmamız gereken Hasar butonuna tıklayınca HasarVer() fonksiyonunu, Sağlık butonuna tıklayınca Wololo() fonksiyonunu çağırmak.

Scripti Main Camera‘ya verip “Slider” değişkenine değer olarak sağlık barını verin. Sonra hasar butonunun “On Click()” listesine “SaglikBari.HasarVer” fonksiyonunu, sağlık butonunun “On Click()” listesine de “SaglikBari.Wololo” fonksiyonunu ekleyin. Artık oyunu test edebilirsiniz.

Scrollbar, Scroll Rect ve Mask

Kullanıcı sözleşmelerini bilirsiniz. Sözleşmenin sonuna ulaşmak için yandaki çubuğu milyon pixel aşağı sürüklememiz gerekir. Biz çubuğu aşağı-yukarı kaydırdıkça sözleşmeyi ekrana çizdiren kutucuktaki yazı da aşağı-yukarı kayar. İşte bu örnekteki çubuk bir Scrollbar, sözleşmeyi ekrana çizdiren kutucuk ise Scroll Rect‘tir.

GameObject menüsünde Scroll Rect‘i göremezsiniz. Scroll Rect bir obje değil bir component‘tir. Rect Transform component’ine sahip herhangi bir objeye Scroll Rect de verilebilir.

Scroll Rect ile ilgili yapacağımız örneğin konusu ne tahmin edin: kullanıcı sözleşmesi! Kullanıcı sözleşmesinin altında ise bir buton olacak ve sözleşmeyi okuduysak butona tıklayıp uygulamayı kullanmaya devam edebileceğiz.

Bu örnek biraz uzun olacak o yüzden adım adım gideceğiz. Öncelikle kullanıcı sözleşmesi için sahnede SozlesmeText adında bir Text oluşturun. Text’in içeriğini istediğiniz gibi doldurun ama oldukça uzun bir sözleşme olmasına dikkat edin. Ardından Text’in yüksekliğini (Height), yazıyı içine tam oturtacak şekilde ayarlayın:

29

Şimdi bu uzun sözleşmeyi scroll edebilmek için bir Scroll Rect oluşturalım. Bu Scroll Rect’i ben bir Panel‘in içinde oluşturmayı uygun buldum. Bunun için ScrollPanel adında yeni bir Panel oluşturun ve panele Component-UI-Scroll Rect yolunu izleyerek bir “Scroll Rect” component’i verin.

Panel, varsayılan olarak tüm canvas’ı kaplar; biz bunu epey bi küçültelim. Paneli, genişliği en azından kullanıcı sözleşmesinin genişliği kadar olacak şekilde boyutlandırın. Ardından panelin yüksekliğini, kullanıcı sözleşmesinin sadece bir kısmını içine alabilecek şekilde daraltın. Panelin arkaplan rengini (Color) beyaz yapın ve panel ile kullanıcı sözleşmesinin üst kenarlarını aynı hizaya getirin:

30

Geriye önemli bir tek şey kaldı: panele (Scroll Rect‘e) scroll edeceği UI elemanının kullanıcı sözleşmesi Text‘i olduğunu bildirmek. Bunu yapmak ise sandığınızdan da kolay: SozlesmeText‘i ScrollPanel‘in bir child objesi yapın ve ardından ScrollPanel‘in “Scroll Rect (Script)” component’inde yer alan “Content“e değer olarak SozlesmeText‘i verin:

31

Oyunu çalıştırıp mouse imlecini ScrollPanel üzerinde sürüklerseniz (veya fare imleci panelin üzerindeyken mouse tekerleğini döndürürseniz) kullanıcı sözleşmesinin o yönde hareket ettiğini göreceksiniz.

Oluşturduğumuz sistemin iki eksiği mevcut: kullanıcı sözleşmesinin panelin dışına taşan kısmı hâlâ ekrana çizdiriliyor ve henüz Scroll Rect‘e bir Scrollbar atamadık.

Bu sorunları çözmeden önce dilerseniz “Scroll Rect (Script)“in sahip olduğu değişkenlere bir göz atalım:

Horizontal: Scroll Rect’teki içeriğin yatay eksende (sağ-sol) kaydırılıp (scroll) kaydırılamayacağını belirler.

Vertical: Scroll Rect’teki içeriğin dikey eksende (yukarı-aşağı) kaydırılıp (scroll) kaydırılamayacağını belirler.

Movement Type: Scroll Rect’teki içeriğin (bizde kullanıcı sözleşmesi Text’i) davranış biçimini belirler. Burada üç farklı mod yer almakta:

  • Unrestricted: İçerik Scroll Rect’in içinde kalmak zorunda olmaz. Şu anda kullanıcı sözleşmesini Scroll Rect’in dışında tutmak mümkün değil ama bu seçeneği seçerseniz bu mümkün olur. Neden böyle birşey isteyesiniz orası tartışılır.
  • Elastic: İçerik Scroll Rect’in dışına ancak mouse ile tutulup sürüklenirken çıkarılabilir. Mouse ile sürükleme işlemi sonlandırıldığında içerik otomatik olarak Scroll Rect’in içerisine geri yerleşir.
  • Clamped: İçeriği Scroll Rect’in dışına çıkarmak hiçbir şekilde mümkün olmaz.

Inertia: Eğer bu seçenek işaretliyse, Scroll Rect’in içeriğini (SozlesmeText) tutup bir yöne hızlı bir şekilde fırlatınca içerik aniden durmaz, yavaşlayarak “yumuşak” bir şekilde durur.

Scroll Sensitivity: Fare tekerleğinin hassasiyetini ayarlar. Bence bu değeri en azından 10 yapın zira 1 iken kullanıcı sözleşmesini tekerleği oynatarak hareket ettirmek tam bir işkence.

On Value Changed(Vector2): Scroll Rect’teki içeriği kaydırdıkça (veya scrollbar’ların konumunu değiştirdikçe) bu listedeki fonksiyonlar çağrılır. Buradaki parametrenin türü Vector2‘dir çünkü horizontal scrollbar değerini x, vertical scrollbar değerini ise y içinde tutan en uygun veri türü Vector2‘dir.

Gelelim az önce bahsettiğim sorunları çözmeye. İlk sorunu çözmek için Mask adındaki bir component‘ten faydalanacağız. ScrollPanel‘i seçin ve Component-UI-Mask yolunu izleyin. O da ne: ScrollPanel’in dışında kalan yazı artık ekrana çizilmiyor!

32

Peki bu nasıl oldu? Mask component’i, Scroll Rect‘in dışına taşan alanı gizlemeye yarar. Mask component’i düzgün çalışmak için bir Image component‘ine ihtiyaç duyar. O Image’in sınırları dahilindeki alan Scroll Rect’in çizdireceği alan, Image’in dışında kalan alan ise Scroll Rect’in çizdirmeyeceği alan olarak belirlenir. Şansımıza, Panel objesi zaten bir Image ile geliyor; bu sayede sadece Mask ekleyerek sorunumuzu çözdük. Panelin Image’ı, panel objesinin arkaplanının kendisi. Bu durumda panelin arkaplanının dışına taşan kısımlar Mask sayesinde çizdirilmemiş oluyor.

Mask component’inin bir değişkeni bulunmakta: “Show Mash Graphic“. Bu seçenek Image‘daki sprite‘nin ekrana çizilip çizilmeyeceğini belirler. Eğer bu seçeneği kapatırsanız panelin arkaplanı görünmez olur.

Geldik ikinci sorunu çözmeye; yani sahneye bir Scrollbar ekleyip bunu Scroll Rect‘e bağlamaya.

Öncelikle GameObject-UI-Scrollbar yolunu izleyerek arayüze bir Scrollbar ekleyin. Farketmişsinizdir; “Scrollbar (Script)“in sahip olduğu değerler “Slider (Script)“inkine “oldukça” benziyor. Burada yer alan yeni değişkenler ise şunlar:

Size: Scrollbar’ın tutacağının boyutunu belirler.

Number of Steps: Eğer bu değer 0 ise scrollbar yumuşak bir şekilde hareket eder, değilse “zıplaya zıplaya” hareket eder. Bunu anlamanın en iyi yolu denemek. Bu değişkenin değerini 3 yapıp oyunu çalıştırın ve scrollbar’ı hareket ettirin. Ne demek istediğimi anlayacaksınız.

Şimdi bizim bu scrollbar’da yapmamız gereken değişiklikler neler? İlk yapmamız gereken şey scrollbar’ı yatay değil dikey hale sokmak. Bunun için Direction‘ı “Bottom To Top” olarak değiştirmeniz yeterli.

Ardından Scrollbar‘ı ScrollPanel‘in sağ kenarına getirin ve yüksekliğini ScrollPanel’inkiyle aynı yapın. Son olarak da ScrollPanel’i seçin ve Inspector‘dan “Vertical Scrollbar” değişkenine değer olarak, az önce oluşturduğunuz Scrollbar‘ı verin. Böyle yaparak Scroll Rect‘i dikey eksende (yukarı-aşağı) hareket ettirecek scrollbar’ı belirlemiş oluyoruz.

Oyunu test edin. Eğer scrollbar düzgün çalışmıyorsa örnek projeyi kontrol edin.

Geriye sadece sözleşmeyi onaylamaya yarayan buton kaldı. Yeni bir Button oluşturup bunu ScrollPanel‘in altına yerleştirin. Button’un ismini “OnayButon” olarak değiştirin:

33

Butona tıklayınca yapılacak şeyleri ayarlayalım. Bunun için “SozlesmeScript.js” adında yeni bir Javascript oluşturun:

#pragma strict

function OnayButonu()
{
	Debug.Log( "SÖZLEŞME ONAYLANDI!" );
}

Scripti Main Camera‘ya verip OnayButon objesinin “On Click()” listesine “SozlesmeScript.OnayButonu” fonksiyonunu ekleyin. Artık butona tıklayınca konsola mesaj yazdırılacak.

Biz onay butonuna, ancak ve ancak sözleşmenin dibine ulaşmışsak (yani scrollbar en alt hizadaysa) tıklanabilmesini istiyoruz. Yani buton, oyunun en başında kullanıcının input’larını yoksayacak. Bunu yapmak basit: OnayButon‘daki “Interactable” seçeneğini kapatın. Artık butona tıklayamıyoruz. Şimdi geriye, sözleşmenin sonuna ulaşınca butonu aktif hale getirmek kaldı.

SozlesmeScript.js scriptini şöyle güncelleyin:

#pragma strict

import UnityEngine.UI;

public var onayButonu : Button;

function OnayButonu()
{
	Debug.Log( "SÖZLEŞME ONAYLANDI!" );
}

function ButonuAktiflestir( deger : float )
{
	if( deger <= 0.1f )
		onayButonu.interactable = true;
}

Main Camera‘daki “Onay Butonu” değişkenine değer olarak OnayButon‘u verin. Ardından Scrollbar objesini seçip “On Value Changed(Single)” listesine “SozlesmeScript.ButonuAktiflestir” fonksiyonunu ekleyin (listeden fonksiyonu seçerken üsttekini seçmeyi unutmayın!).

Naptık derseniz şöyle yaptık: artık Scrollbar‘ın değeri değiştikçe ButonuAktiflestir fonksiyonu çağrılıyor ve scrollbar’ın değeri (value) fonksiyondaki “deger” parametresine aktarılıyor. Scrollbar’ın “Direction“ı “Bottom To Top” olduğu için, eğer scrollbar tepedeyse “value” 1, dipteyse “value” 0 değerini alır. Bu bilgiyi kullanarak, eğer “deger” değişkeninin değeri 0.1’den küçükse, yani scrollbar epey dipteyse (oyuncu mecburen sözleşmeyi aşağı kaydırdıysa) OnayButon‘un “Interactable” değişkenini true yapıyoruz ve böylece artık butona tıklayabiliyoruz.

Bu örnekle birlikte hemen hemen tüm UI elemanlarını görmüş olduk. Geriye anlatacak birkaç ufak detay kaldı sadece.

Bir UI Elemanına Basılı Tutulduğu Sürece Yapılacak Şeyleri Belirlemek (Event Trigger Sistemi)

Butonu ele alalım. Butona tıkladığımızda istediğimiz bir fonksiyonu çağırabiliyoruz. Ama diyelim ki biz, butona basılı tuttuğumuz sürece bir fonksiyonu çağırmak istiyoruz. Bu durumda “Event Trigger” adında bir component kullanılır. Buton, varsayılan olarak sadece “On Click()” event’ine destek verirken Event Trigger ile daha fazla event desteklemesi sağlanabilir.

Bu konuyla ilgili iki örnek uygulama yapacağız. İkisinde de butonlar üzerinden gideceğiz. İlk örnek ile başlayalım isterseniz…

Yeni bir scene açıp içinde bir tane buton oluşturun. Butona RenkButon ismini verin. Yapmak istediğimiz şey şu: bu butona basılı tuttuğumuz sürece butonun arkaplan rengi değişecek. Butona basılı tuttuğumuz sürece bir iş yaptırmak için Event Trigger‘ı kullanacağız. Butonu seçin ve Component-Event-Event Trigger yolunu izleyin.

Inspector panelinde Event Trigger component‘i belirecek. Bu component şu anda birşey yapmıyor çünkü henüz o UI elemanına uygulanacak özel bir event seçmedik. Mevcut event’lerin listesini görmek için “Add New Event Type” butonuna tıklayın:

34

Burada oldukça fazla sayıda event yer almakta. Ben bunlar arasından bildiklerimi sizlerle paylaşayım:

PointerEnter: Mouse imleci bu UI elemanının üzerine geldiği anda tek seferlik çalıştırılır.

PointerExit: Mouse imleci bu UI elemanının üzerinden çekildiği anda tek seferlik çalıştırılır.

PointerDown: Bu UI elemanına mouse/parmak ile dokunulduğu anda tek seferlik çalıştırılır.

PointerUp: Bu UI elemanına mouse/parmak ile dokunma işlemi sonlandırıldığı anda tek seferlik çalıştırılır.

PointerClick: Button‘daki “On Click()” ile aynı şeyi yapar. Yani bu UI elemanına mouse/parmak ile click yapıldığında (tıklanıp hemen ardından bırakıldığında) tek seferlik çalıştırılır.

Drag: Bu UI elemanına mouse/parmak basılı durumda iken mouse/parmak her hareket ettirildiğinde çalıştırılır. Bu event’i OnMouseDrag() ile karıştırmayın. OnMouseDrag() fonksiyonu, bir objeye basılı tuttuğumuz sürece çalıştırılıyordu ve bu esnada mouse’u/parmağı hareket ettirip ettirmediğimiz önemsizdi. Ancak Drag event’inde yer alan fonksiyonların çağrılması için mouse’un/parmağın hareket etmesi şart.

Burada bahsettiğim event’ler hemen her durum için yeterlidir. Diğer event’leri dilerseniz kendiniz araştırabilirsiniz.

EventScript.js” adında yeni bir Javascript oluşturun:

#pragma strict

import UnityEngine.UI;

public var arkaplan : Image;
private var drag : boolean = false;
private var renkRGB : Vector3 = Vector3.one;

function ButonaTiklandi()
{
	drag = true;
}

function ButonBirakildi()
{
	drag = false;
}

function Update()
{
	if( drag )
	{
		renkRGB += new Vector3( 0.1f, 0.2f, 0.3f ) * Time.deltaTime;
		var arkaplanRenk : Color = new Color();
		arkaplanRenk.r = Mathf.PingPong( renkRGB.x, 1f );
		arkaplanRenk.g = Mathf.PingPong( renkRGB.y, 1f );
		arkaplanRenk.b = Mathf.PingPong( renkRGB.z, 1f );
		arkaplanRenk.a = 1f;
		arkaplan.color = arkaplanRenk;
	}
}

Az önce Drag event’ini açıklarken bahsettim: Drag event’inin çalışması için mouse’un hareket halinde olması lazım. Oysa biz, mouse’u sabit tuttuğumuz sürece de butonun renginin değişmesini istiyoruz. Bizim rengi değiştirirken aradığımız tek koşul butona basılı tutuyor olmak.

Bunun için şöyle bir yol düşündüm: butona dokunulduğu anda ButonaTiklandi() fonksiyonunu çağıracağız ve “drag” adındaki bir değişken true değerini alacak. Butonu bıraktığımızda ise ButonBirakildi() fonksiyonunu çağıracağız ve “drag” değişkeni false değerini alacak. Update() fonksiyonunda ise “drag”ın değerinin true olup olmadığına bakacağız ve eğer true ise “arkaplan” değişkeninde tutulan UI elemanının (butonun) arkaplan rengini değiştireceğiz (Update() fonksiyonu içinde yaptığımız tek şey “arkaplan” objesinin arkaplan rengini değiştirmek; kodun uzun olduğuna bakmayın).

O halde planımızı uygulamaya sokalım. İlk iş olarak Main Camera‘ya “EventScript.js” scriptini verin. Script’teki “Arkaplan” değişkenine değer olarak RenkButon objesini verin. Sonrasında RenkButon objesinin Event Trigger component’ine gelin ve buraya bir PointerDown event’i ekleyin. Event gerçekleşince çağrılacak fonksiyonlar listesine ise kameradaki EventScript.ButonaTiklandi fonksiyonunu ekleyin. Ardından Event Trigger’a bir de PointerUp event’i ekleyin ve bu event’e de EventScript.ButonBirakildi fonksiyonunu ekleyin:

35

Oyunu test edin. Butona basılı tuttuğunuz sürece butonun arkaplan rengi değişmeli. Birşeyler düzgün çalışmıyorsa örnek projeyi kontrol edebilirsiniz.

Geldik ikinci örnek uygulamaya. Bu örnekte de ekranda bir buton olacak ve bu butonu oyun sırasında fare ile tutup sürükleyerek istediğimiz yere taşıyabileceğiz.

Bu sefer yeni bir sahne oluşturmanıza gerek yok. Sadece sahnede yeni bir buton oluşturup onu önceki butondan farklı bir yere taşıyın. Bu butona HareketButon adını verin. Sonra bu butona da Event Trigger component’i ekleyin.

Artık “EventScript.js” scriptini güncellemeye hazırız:

#pragma strict

import UnityEngine.UI;
import UnityEngine.EventSystems;

public var arkaplan : Image;
private var drag : boolean = false;
private var renkRGB : Vector3 = Vector3.one;

function ButonaTiklandi()
{
	drag = true;
}

function ButonBirakildi()
{
	drag = false;
}

function Update()
{
	if( drag )
	{
		renkRGB += new Vector3( 0.1f, 0.2f, 0.3f ) * Time.deltaTime;
		var arkaplanRenk : Color = new Color();
		arkaplanRenk.r = Mathf.PingPong( renkRGB.x, 1f );
		arkaplanRenk.g = Mathf.PingPong( renkRGB.y, 1f );
		arkaplanRenk.b = Mathf.PingPong( renkRGB.z, 1f );
		arkaplanRenk.a = 1f;
		arkaplan.color = arkaplanRenk;
	}
}

function ButonSurukleniyor( data : BaseEventData )
{
	var mouseData : PointerEventData = data as PointerEventData;
	mouseData.pointerPress.transform.Translate( mouseData.delta );
}

Tek yaptığımız şey scripte ButonSurukleniyor adında yeni bir fonksiyon eklemek oldu. Bu fonksiyonu, butonun Drag event’inde çağıracağız.

Event fonksiyonlarında eğer ki mouse’un/parmağın konumuna, hareket etme miktarına vb. erişmek istiyorsanız o zaman fonksiyona BaseEventData türünde bir parametre eklemek zorundasınız; parametrenin ismi önemli değil (ben “data” ismini verdim). Sonra script içerisinde bu parametreyi PointerEventData‘ya typecast yapmalısınız (ben bu değişkene “mouseData” ismini verdim). Artık PointerEventData türündeki değişkeni kullanarak mouse/parmak ile ilgili detaylı bilgilere erişebilirsiniz.

PointerEventData‘yı kullanarak erişebileceğimiz önemli bilgiler neler diye soracak olursanız:

button: UI elemanına hangi fare tuşuyla tıklanıldığını depolar. Üç değer alabilir:

  • InputButton.Left: Sol mouse tuşu
  • InputButton.Middle: Orta mouse tuşu
  • InputButton.Right: Sağ mouse tuşu

clickTime: UI elemanına tam olarak ne zaman tıklanıldığını depolar.

delta: Bu event esnasında mouse’un/parmağın ekranda kaç pixel hareket ettiğini depolar.

position: Mouse’un/parmağın ekrandaki mevcut konumunu depolar.

pointerPress: Tıklanılan UI elemanını GameObject türünde depolar.

Peki biz fonksiyonda ne mi yapıyoruz? Önce pointerPress ile tıkladığımız butona (GameObject olarak) erişiyoruz. Sonra bu GameObject‘in Transform component’ine erişiyoruz. Sonra da Translate fonksiyonu ile bu objeyi hareket ettiriyoruz. Peki ne kadar hareket ettiriyoruz? delta kadar; yani mouse’un yatay ve dikey eksende oynadığı pixel sayısı kadar.

NOT: ButonSurukleniyor fonksiyonunun düzgün çalışması için scriptin başına “import UnityEngine.EventSystems;” komutu eklemek zorundaydık çünkü BaseEventData ve PointerEventData class’ları UnityEngine.EventSystems package‘ında yer almaktadırlar.

Geriye sadece HareketButon‘daki Event Trigger‘a Drag event‘i ekleyip bu event’te EventScript.ButonSurukleniyor fonksiyonunu çağırmak kaldı:

36

Oyunu test ederseniz butonun fare ile sürüklenebildiğini göreceksiniz. Tebrikler!

Arayüzün Her Çözünürlükte Aynı Görünmesini Sağlamak

Button’u işlerken anchor‘ları kullanarak arayüz elemanlarının arayüzle beraber nasıl boyutlanabileceğini gördük. Ancak bazen özel durumlar olur. Örneğin arayüzde bir resim çizdiriyorsunuz diyelim. Resmin anchor’larını canvas’ın dört bir köşesine yaydınız; resim canvas ile büyüyüp küçülüyor. Ama burada ufak bir sıkıntı var: resmin en/boy oranı (aspect ratio) korunmuyor! Bu, butonlar için bir sıkıntı değil ama bir resim çizdirirken genelde resmin en/boy oranının korunmasını isteriz. Bu gibi durumlarda yeni UI sisteminin bize sağladığı birkaç seçenek mevcut:

Aspect Ratio Fitter

Bu component, atandığı UI elemanının en/boy oranının daima aynı kalmasını sağlar. Bu component’i Component-Layout-Aspect Ratio Fitter yolunu izleyerek istediğiniz UI elemanına verebilirsiniz. Component’in sahip olduğu “Aspect Mode” değişkeni burada önem arz ediyor:

37

Bu seçenekler sırayla şöyle:

None: Component işlevini kaybeder.

Width Controls Height: UI elemanının genişliği değiştikçe; yüksekliği, en/boy oranını koruyacak şekilde otomatik olarak değiştirilir.

Height Controls Width: UI elemanının yüksekliği değiştikçe; genişliği, en/boy oranını koruyacak şekilde otomatik olarak değiştirilir.

Fit In Parent: UI elemanının ya genişliği ya da yüksekliği daima parent objenin kenarlarıyla temas halinde olur (bu esnada en/boy oranı korunur).

Envelope Parent: UI elemanı, parent objesinin tamamını içine alacak şekilde otomatik olarak boyutlandırılır (bu esnada en/boy oranı korunur).

Son iki seçenek benim pek ilgimi çekmedi ama ondan önceki iki seçenek gerçekten kullanışlı duruyor. Bu iki seçeneği kullanarak hazırladığım örnek bir scene’i, örnek projenin içinde bulabilirsiniz.

Bu component’i kullanırken bilmeniz gereken önemli bir nokta daha var: pivot noktasının konumu. Eğer ki UI elemanının hep ekranın en sol üstünde yer almasını istiyorsanız ve Aspect Ratio Fitter component’ini kullanıyorsanız o zaman pivot noktasını UI elemanının sol üst köşesine taşımalısınız. Böylece UI elemanının otomatik olarak boyutlandırılması sağ ve alt kenarlar üzerinden gerçekleşecek, sol üst noktanın konumu değişmeyecek.

Canvas Scaler

Bu component benim gerçekten çok hoşuma gidiyor; kullanması da gayet basit:

Öncelikle Game panelinin sol üstündeki çözünürlük butonu vasıtasıyla çözünürlüğü 1024×768 yapıyoruz:

38

Sonra Canvas objesini seçiyoruz ve “Canvas Scaler (Script)” component’inin “Ui Scale Mode“unu “Scale With Screen Size” yapıyoruz. Karşımıza gelen yeni değişkenlerden referans çözünürlüğü 1024×768 yapıyor, “Screen Match Mode“u ise “Expand” yapıyoruz:

39

Artık arayüzümüzü hazırlamaya hazırız. Arayüzü hazırlarken dikkat etmemiz gereken nokta, UI elemanlarının anchor noktalarını dört farklı noktaya yaymak yerine bir noktada toplamak. Örnek projede bu konuyla ilgili de ufak bir örnek mevcut; incelemenizi öneririm.

NOT: Canvas Scaler‘ın sahip olduğu diğer değişkenleri araştırmak size düşmüş; onların nolduğunu ben de tam bilmiyorum.

3 Boyutlu (3D) Arayüzler Oluşturmak

UI sisteminin en güzel yanlarından birisi budur kesinlikle. Artık 3 boyutlu düzlemde bir pozisyon ve eğime sahip arayüzler oluşturabiliyoruz. Örneğin sitemde paylaştığım Infinite Runner örneğindeki ( https://yasirkula.com/2015/01/15/unity-3d-temple-run-tarzi-infinite-runner-oyun-ornegi/ ) 3D skor yazısını UI sistemi ile oluşturdum.

Peki nasıl üç boyutlu arayüz oluşturuyoruz? Canvas objesini seçiyorsunuz ve “Canvascomponent‘indeki “Render Mode“u “World Space” ile değiştiriyorsunuz. Bu kadar! Ardından canvas’ı Scale aracıyla “oldukça” küçültmek isteyebilirsiniz.

3D arayüz ile ilgili örnek bir uygulama yapmayacağız çünkü bence bu çok basit bir konu, anlatılacak pek birşey yok. Ancak önemli sayılabilecek bir nokta var onu paylaşayım: eğer ki 3D arayüzünüzde yazılar bulanık görünüyorsa Canvas‘ın “Canvas Scaler (Script)” component’indeki “Dynamic Pixels Per Unit” değerini artırmayı deneyin.

3 boyutlu arayüz ile ilgili örnek bir scene‘i örnek projede bulabilirsiniz. Örnekten bir resim:

40

Bu uzun dersin burada sonuna gelmiş bulunmaktayız. Umuyorum ki az biraz faydalı olmuştur. Eğer ki konuya ilginiz varsa o zaman Unity’nin resmî video tutoriallerini izlemenizi şiddetle öneririm: http://unity3d.com/learn/tutorials/modules/beginner/ui

Sonraki derslerde görüşmek dileğiyle!

Yorumlar
  1. ibrahim YILMAZ diyor ki:

    çok sağ ol sen olmasan biz ne yapardık çalışmalarının devamını bekliyoruz abi.

  2. Enes Tulga diyor ki:

    ellerine sağlık

  3. Fatih Emre Kurşun diyor ki:

    Eline sağlık usta,Unity’nin mecanim sistemi hakkında da bilgin varsa ders hazırlayabilirmisin.Combat move tarzında yakın savaş animasyonları için mecanim mi kullanmak gerekir sence

  4. ibrahim YILMAZ diyor ki:

    abi yapay zeka ile ilgili kaynak pek yok yapay zeka dersleri paylaşa bilir misin ?
    sadece bizi takip edecek şekilde değilde
    yada şöyle deyim benim oyunumda karakterin 3 hareketi var 2d yol gibi düşün sağa doğru git, sola doğru git ve bekle şeklinde. bir türlü yapamadım senin derslerinde ki zombie yürüme animasyonunu denedim karakter ışınlanarak gidiyor ve çok hızlı bir şekilde oluyor. çözemedim bir türlü.
    switch (Random.Range(0, 3))
    {
    default:
    case 0:
    transform.Translate (10*Time.deltaTime,0, 0);
    break;
    case 1:
    transform.Translate (-20*Time.deltaTime,0, 0);
    break;
    case 2:
    transform.Translate (0,0, 0);
    break;
    }

    hem bu en basit hali düşman varsa saldır falan olacak da onlarla ilgili dersler zaten var.
    switch mantığı doğrumu yoksa farklı bir şekilde mi yapmam gerekir.
    yardım edersen çok sevinirim. ^-^

  5. Ahoo diyor ki:

    yasir abi bi android araba projesi yapsan keşke yha

  6. rıdvan diyor ki:

    çok güzel bi anlatım. ellerine sağlım yasir kula anlatımlarının devamını ve örnek projeler bekliyoruz
    sen bizim Türkçe kaynağımızsın 😀

  7. ahmetcankisactutan diyor ki:

    Yasir Bey,Oyunu Build etmeye çalışırken şöyle bi hata aldım..Reklam eklemeden önce hata vermiyodu..Yardım ederseniz çok sevinirim..

    Error building Player: CommandInvokationFailure: Failed to re-package resources. See the Console for details.
    C:\Users\ahmetcan\Downloads\adt-bundle-windows-x86_64-20140702\sdk\build-tools\21.1.1\aapt.exe package –auto-add-overlay -v -f -m -J gen -M AndroidManifest.xml -S “res” -I “C:/Users/ahmetcan/Downloads/adt-bundle-windows-x86_64-20140702/sdk/platforms/android-21\android.jar” -F bin/resources.ap_

    stderr[
    AndroidManifest.xml:9: error: Error: No resource found that matches the given name (at ‘value’ with value ‘@integer/google_play_services_version’).

    ]
    stdout[
    Configurations:
    (default)
    ldpi-v4
    hdpi-v4
    xhdpi-v4
    xxhdpi-v4
    xxxhdpi-v4

    Files:
    drawable\app_icon.png
    Src: () res\drawable\app_icon.png
    Src: (ldpi-v4) res\drawable-ldpi\app_icon.png
    Src: (hdpi-v4) res\drawable-hdpi\app_icon.png
    Src: (xhdpi-v4) res\drawable-xhdpi\app_icon.png
    Src: (xxhdpi-v4) res\drawable-xxhdpi\app_icon.png
    Src: (xxxhdpi-v4) res\drawable-xxxhdpi\app_icon.png
    values\strings.xml
    Src: () res\values\strings.xml
    AndroidManifest.xml
    Src: () AndroidManifest.xml

    Resource Dirs:
    Type drawable
    drawable\app_icon.png
    Src: () res\drawable\app_icon.png
    Src: (ldpi-v4) res\drawable-ldpi\app_icon.png
    Src: (hdpi-v4) res\drawable-hdpi\app_icon.png
    Src: (xhdpi-v4) res\drawable-xhdpi\app_icon.png
    Src: (xxhdpi-v4) res\drawable-xxhdpi\app_icon.png
    Src: (xxxhdpi-v4) res\drawable-xxxhdpi\app_icon.png
    Type values
    values\strings.xml
    Src: () res\values\strings.xml
    Including resources from package: C:\Users\ahmetcan\Downloads\adt-bundle-windows-x86_64-20140702\sdk\platforms\android-21\android.jar
    applyFileOverlay for drawable
    applyFileOverlay for layout
    applyFileOverlay for anim
    applyFileOverlay for animator
    applyFileOverlay for interpolator
    applyFileOverlay for transition
    applyFileOverlay for xml
    applyFileOverlay for raw
    applyFileOverlay for color
    applyFileOverlay for menu
    applyFileOverlay for mipmap
    Processing image: res\drawable\app_icon.png
    Processing image: res\drawable-ldpi\app_icon.png
    (processed image res\drawable-ldpi\app_icon.png: 98% size of source)
    Processing image: res\drawable-hdpi\app_icon.png
    Processing image: res\drawable-xhdpi\app_icon.png
    Processing image: res\drawable-xxhdpi\app_icon.png
    (processed image res\drawable-hdpi\app_icon.png: 97% size of source)
    Processing image: res\drawable-xxxhdpi\app_icon.png
    (processed image res\drawable-xhdpi\app_icon.png: 97% size of source)
    (processed image res\drawable\app_icon.png: 98% size of source)
    (processed image res\drawable-xxhdpi\app_icon.png: 98% size of source)
    (processed image res\drawable-xxxhdpi\app_icon.png: 97% size of source)
    (new resource id app_icon from drawable\app_icon.png #generated)
    (new resource id app_icon from ldpi-v4\drawable\app_icon.png #generated)
    (new resource id app_icon from hdpi-v4\drawable\app_icon.png #generated)
    (new resource id app_icon from xhdpi-v4\drawable\app_icon.png #generated)
    (new resource id app_icon from xxhdpi-v4\drawable\app_icon.png #generated)
    (new resource id app_icon from xxxhdpi-v4\drawable\app_icon.png #generated)
    ]

  8. ahmetcankisactutan diyor ki:

    Hata şöyle bişi ;
    Error building Player: Win32Exception: ApplicationName=’javac.exe’, CommandLine=’-bootclasspath “C:/Users/ahmetcan/Downloads/adt-bundle-windows-x86_64-20140702/sdk/platforms/android-21\android.jar” -d “C:\Users\ahmetcan\Documents\New Unity Project\Temp\StagingArea\bin\classes” -source 1.6 -target 1.6 -encoding UTF-8 “com\google\android\gms\R.java” “com\Vivor\CrazyRotatePuzzle\R.java”‘, CurrentDirectory=’C:\Users\ahmetcan\Documents\New Unity Project\Temp\StagingArea\gen’

    • ahmetcankisactutan diyor ki:

      Bunu da çözdüm teşekkürler 🙂

      • yasirkula diyor ki:

        Bahsettiğiniz hataları sırayla nasıl çözdüğünüzü altlarına yazarsanız aynı sorunu alanlara büyük yardımınız dokunabilir. Şimdiden elinize sağlık.

      • ahmetcankisactutan diyor ki:

        Tabi ki..Zaten siz dersleriniz de çoğunun çözümünden bahsetmişsiniz.Bir de sizden bir ricam olacak; “Uyguluma içi Satın alma” ve “oyunları facebook’ta yayınlama” ilgili dersler hazırlayabilirseniz çok yardımcı olur..Biliyorsunuz reklam gelirleri yerlerde sürünüyor artık..

    • Ali diyor ki:

      Kardeş aynı hatayı bende aldım nasıl yapıldığını açıklarsan banada yardımcı olmuş olursun.

  9. ahmetcankisactutan diyor ki:

    İlk oyunum sayenizde tamamlandı Yasir Bey çok teşekkür ederim.Şu an Samsung Store de onay sürecinde ilgiye ve yorumlara göre W.phone ve ios’a da buil edicem ama play store’a girmeyi düşünmüyorum.Credits bölümünde size de ufak bir teşekkürde bulundum umarım kabul edersiniz.Şimdi ikinci projeye başlama zamanı.Menajerlik tarzı (menejerlik yapmayacağım) bir oyun için textlerden oluşan Ogame gibi düşünebiliriz ancak online olmayacak.böyle bir oyun için hangi programı kullanmalıyım?

  10. suleyman aktaş diyor ki:

    Kolay Gelsin arkadaşlar. Ben bir oyun hazırlıyorum ama bir noktada sıkıştım kaldım. Kule savunması benzeri bir oyun yapıyorum ama sorunum şu. Ekranda düşman kalmayınca sol üstte “next” diye bir buton çıkmasını istiyorum ve nexte basıldığında bir sonraki scene yüklenmeli. Bunu nasıl yapabilirim.? düşmanlar bir prefabtan spawn ediliyor ve bir noktaya ilerlemeye çalışıyor. Yardımlarınız için şimdiden teşekkurler…

    • suleyman aktaş diyor ki:

      Bu arada konuyu yanlış yerde sordum kusura bakmayın.

      • yasirkula diyor ki:

        public static bir değişken olsun, ismi dusmanSayisi, türü int olsun. Spawner objesinin Start fonksiyonunda bu değişkenin değerini, spawn’lanan düşman sayısına eşitleyin. Oyun sırasında her düşman öldürünce bu değişkeni bir azaltın. Değişken 0 olmuşsa “Next” butonunu aktif hale getirin.

    • Nihat Yıldız diyor ki:

      kardeşim düşmanların tagını Finish Yap ve scripti playere at sonra buton kısmına etkinleşmesini istediğin butonu at tamamdır 🙂

      var buton : GameObject;

      function Start () {

      buton.active =false;
      }

      function Update () {
      if(GameObject.FindGameObjectsWithTag(“Finish”).Length<1){
      buton.active = true;
      }

  11. suleyman aktaş diyor ki:

    her düşman ölünce bir azaltma kısmında sıkıntı var sanırım benım. o dedıklerınızı yapmıstım ama düşman olunce ondeath fonksiyonunda Destroy game object dedıkten sonra dusmanSayisi– yapıyorum ama çalıştıramadım bir türlü

    • suleyman aktaş diyor ki:

      yani spawner objesinın scriptiyle dusman prefabının scriptleri birbirinden farklı scriptler. getcomponentle almaya calıştım ama onu da yapamadım kafayı yicem

      • yasirkula diyor ki:

        static değişken burada işe yarıyor. Spawner scriptinin ismi DusmanSpawner ise tek yapmanız gereken şu:

        DusmanSpawner.dusmanSayisi--;

      • suleyman aktaş diyor ki:

        cok tesekkur ederım dostum hallettım sayende. adamsın kralsın 😀

  12. turak1905 diyor ki:

    butona basılı tutunca bi olayın olmasını nasıl yapabiliriz…

    • yasirkula diyor ki:

      “Bir UI Elemanına Basılı Tutulduğu Sürece Yapılacak Şeyleri Belirlemek (Event Trigger Sistemi)” başlığı altında bunu anlattım.

  13. Yasin diyor ki:

    yasir abi benim yaptığı menülerde yazılar butonlar vs. küçük cihazlarda çok büyük oluyor bunu nasil hallederiz bi yardımci olurmusun ?

    • yasirkula diyor ki:

      Anchor’ları yerleştirirken dikkatli olmanız lazım. Yazıda anchor’lardan bahsettim yazıyı daha iyi okuyun derim. Buna ek olarak “Arayüzün Her Çözünürlükte Aynı Görünmesini Sağlamak” başlığındaki bilgiler de işinize yarayabilir.

  14. Muhammed diyor ki:

    canvas yerine başka neler kullanılabilir veya unity 3d yi güncellemek mi gerek yoksa tekrar baştan mı indirmemiz gerek yeni sürümünü bu özellikleri kullanabilmek için

  15. leonsa17 diyor ki:

    Merhaba. Yaptığım butonun başka bir scene i yani asıl oyunun bir bölümünü başlatmasını nasıl sağlarım?

  16. MustafaBektasoglu diyor ki:

    UI sisteminde InputField içine yazılan sayiyi nasıl baska bir sayıyla carparım yani bir tuşa basıca InputField içine yazılan sayiyi 5 le çarpacam ? nasıl olur

  17. mehmet can bozgun diyor ki:

    iyi günler benim bir sorum var bu asset storeden bir oyun indirdik diyelim örnek bi oyun projesi. bu projeyi çalıştırmak için tek tek her şeyi kendim düzenlemem mi gerekiyor yoksa direk importladıktan sonra çalışırmı örnek olarak karakter lazım bana karakterin modelini atsam hareket ettirebilirmiyim yoksa bütün scriptleri elle atmak zorundamıyım

    • yasirkula diyor ki:

      Örnek bir oyun projesi indirdiyseniz herşeyin otomatik çalışması lazım.

      • mehmet can bozgun diyor ki:

        normalde direk playeri hierarchy paleline sürüklediğimde karakter animasyonlu bi şekilde olması gerekiyor fakat sürüklediğim zaman sadece karakter yürüyüp zıplıyor animasyonları scriptle kontrol etmeli miyim biraz kurcaladım ama fayda etmedi

      • yasirkula diyor ki:

        Bu soruyu sadece o asset’i yapan kişi doğru şekilde cevaplayabilir.

  18. Merhaba Hocam bir sorum olacak oyun yapmakla ilgili her şeyi anladımda bir tek şu oyunda film gibi seyrediyoruz ya onu nasıl yapa bilirim. mesela bir yere geldik adam bizimle konuşmaya başlıyor sağa sola gidiyor bize bir şey veriyor (başka bir şeyde olabilir) yani biz sadece seyr ediyoruz ve konuşma bittiyinde gide biliyoruz. bir fikriniz varmı?

  19. Özgür diyor ki:

    Butonla bir nesneyi nasıl döndürebilirim ? kendi ekseni etrafında.

  20. Özgür diyor ki:

    Düz tek renk ve 4 adet bir arkaplan resmim var bunu her oyuna basladıgında arkaplanı rastgele nasıl getirebilirim.

    • yasirkula diyor ki:

      0’dan 3’e kadar (3 dahil) rastgele bir sayı üretmek için Random.Range( 0,4 ); fonksiyonunu kullanabilirsiniz. Döndürülen sonuca göre arkaplanı değiştirirsiniz.

  21. Nihat Yıldız diyor ki:

    Hocam ben bu canvası yapıyorum

    güzel ama

    pc veya web player için import edince canvas butonları işlemini güzel bir şekilde yapıyor mesela
    butona tıklayınca oyundan çıkş yapsın bunu ben yaptım canvasa attım

    buton pcde güzel bir biçimde işlemini yapıyor ama androide import edince butona tıklayabiliyorum ama istediğim işlemleri yapmıyor

    yani kısacası buton pc için import edildiğinde veya önizlendiğinde güzel bir şekilde çalışıp dediğim fonksiyonu çalıştırıyor ama androidde import edince butona tıklayorum istediğim butonu çalıştırmıyor

    bu sorunu nasıl düzeltebilirim yardımcı olurmusunuz ?

  22. gorkem diyor ki:

    unity 5.0 a geçmelimiyim + ve – yönleri neler yani grafik kalitesi mi artıyor ne farkı var

    • yasirkula diyor ki:

      5’in scene paneli bende takıldığı için ben 4.6’ya geri döndüm. Ama takılma olmasaydı 5’te kalırdım zira profiler ve post-processing effects gibi kaliteli araç gereçler Unity 5 ile ücretsiz kullanıma sunulmuş durumda.

  23. Nihat Yıldız diyor ki:

    Hocam siz temple run örneğinizde OnClick Metodunu Kullanmışsınız ben event trigger ile PointerUp ve PointerDown metodunu kullanarak aracıma gaz ve fren işlemini yapıyorum

    aracım pcde gayet düzgün çalışıyor ama androide build edince aracımın gaz ve fren butonu çalışmıyor

    • yasirkula diyor ki:

      Unity Remote kullanıyorsanız onun yerine APK build alıp telefona atın ve oyunu öyle yükleyip test edin. Kullanmıyorsanız sorunun sebebini bilmiyorum, yaşamadım böyle bir sorun.

    • Mehmet Yüksel diyor ki:

      Oyunumdaki canvas pcde düzgün gözüküyor fakat telefona apksını atıp kurdugumda bazıları gözükmüyor dengesizleşiyor sebebi nedir acaba

      • Mehmet Yüksel diyor ki:

        Pardon yanlışıkla buraya yazmışım yorumları okurken dikkat etmedim birde şeyi sorucaktım ben oyunumda herzaman yatay ekran oynansın istiyorum bunun için bir kod varmı dikey çalışmasını engelliyecek
        şimdiden saolun

      • yasirkula diyor ki:

        Player Settings’te “Resolution and Presentation” sekmesi altında yer alan “Default Orientation” değişkenini Landscape yapabilirsiniz.

      • Mehmet Yüksel diyor ki:

        Yatay ekranı kurcalıyarak buldum fakat canvasın dagılmasını ayarlıyamadım. Bu arada oyunum telefonda inanılmaz kasıyor hele hele bi yerde scene degişimi yapmıştım orda bayağı bekliyor

      • yasirkula diyor ki:

        Ekranın en/boy oranı değiştiği vakit arayüz artık tasarladığınızla birebir aynı olmaz. Ancak arayüz elemanlarını anchor ve pivot kullanarak köşelere sabitleyebilirsiniz. Böyle yaparsanız ekranın aspect ratio’su değişse de o elemanlar hep köşede kalır. Ayrıca “Canvas Scaler” component’indeki “Ui Scale Mode”u “Scale With Screen Size” yaparsanız arayüz sürekli istediğiniz gibi kalabilir (test etmeniz lazım).

      • Mehmet Yüksel diyor ki:

        teşekkürler ekran aylarınıda yaptım şunuda ögrendim mümkün oldukça programı kurcalamak gerekiyormuş iki sorunumuda kurcalıyarak buldum 🙂

  24. gencer diyor ki:

    formda bayadır geziyorum yazılanlarla cevaplarınıza bakıyorum, çok yoğun gerçekten bu soruyu soriyimmi sormiyim mi tereddütte kaldım 😀 , bu güne kadar hiç takıldığım yer olmadı çoğu bilgi için gerçekten çok teşekkür ederim, sorum şu: eski sürümlerde GUISkin le yapılan menülerin veya göstergelerin hareket etmesi için animasyon veya script yöntemi varmı,aynı sorum yeni sürüm içinde gerçerli, şimdiden kolay gelsin teşekkürler 🙂

    • yasirkula diyor ki:

      GUI elemanının Rect’ini public değişken yapıp bu Rect’in değerini Animation ile değiştirebilirsiniz. Daha kolay bir yol düşünemedim.

  25. fatihkaya420ali diyor ki:

    unity 5 i tercih edermisiniz _?

  26. Özgür diyor ki:

    Hocam altın aldıktan sonra ekran +3 puan seklınde bir yazı yazsın istiyorum bunu nasıl yapabilirim ? ve yazı kaybolsun

    • yasirkula diyor ki:

      Bir Plane ya da Quad objesine +3 texture’si atarsınız ve Update fonksiyonunda renderer.material.color.a değerini azaltarak zamanla objenin saydamlaşmasını sağlarsınız. Objeyi yok etmek için Destroy komutunu kullanırsınız.

      Ben fikir verdim, kodu yazmak ise sizin işiniz.

  27. muhammed diyor ki:

    Merhabalar ben canvasta bir buton ekledim ama butona bastığımda basıldığına dair bir tepki vermiyor acaba sorun ne olabilir.. Butonun çalışmasını demiyorum hani tepki verse çalışıp çalışmadığını anlayabilirim..

    • yasirkula diyor ki:

      Button (Script)’teki Interactable seçeneği işaretli olmayabilir. Onun dışında olası bir sebep göremiyorum.

      • muhammed diyor ki:

        yok oda işaretli ama böle basılmıyor butona hani basıldığını hissettirmiyor renkleri falan da ayarladım basıldığında ne renk olsun diye ama yine bişey olmuyor

      • yasirkula diyor ki:

        Yeni bir buton oluşturunca onda da aynı sorun varsa belki EventSystem objesi eksiktir, bilemiyorum.

  28. lal13 diyor ki:

    Unity ücretsiz oldu makale yazabilirsiniz.

    • yasirkula diyor ki:

      Aslına bakarsanız zaten ücretsizdi, şimdi sadece Pro özelliklerinin bir kısmı daha ücretsiz hale geldi. Bu özelliklerden önemli olanlarını tanıtan bir yazı yazabilirim elbet.

  29. Merhaba Hocam biliyorum bu siteye çok soru sordum ))) ama sizden yine bir şey öğrenmek istiyorum ben oyunun haritasını, senaryoyu, düşmanı hazırladım ama istediğimi bulamadım ben düşmanın üzerine ışık tuttuğumda saldırmamasını ve saklandığımızda bizi bulmamasını istiyorum . benim oyunum outlast ve slender man tarzı olacak ama senaryo başka ve eminim tutacak bir oyun olacak sadece bir sorunum var oda dediğim gibi düşmandan kurtulmak (duvar arkasında saklanarak , otların arasında saklanarak) yolunu bulmak istiyorum öyle bir şey varsa kod falan söylermisiniz ? söz veriyorum oyunum bitince sizin siteyi de reklam yaparım )))

  30. Özgür diyor ki:

    transform.Translate(0.1f,0,0); Hocam bu kodla topu aşagı düşerken saga sola goturuyorum .. Topun asagıya dusmesınıde Rigidbody 2D gravity degeri ile yaptım fakat oyunu test ettigimde saga sola goturme hızı Bir telefonda hızlı calısıyor Bir telefonda yavas calısıyor sorun nerededir acaba ?

  31. Özgür diyor ki:

    hocam o zamanda hiç çalısmıyor ..

  32. Özgür diyor ki:

    Hocam topum oyunda bir zaman sonra ekrandan kayboluyor

  33. fatihkaya420ali diyor ki:

    iyi günler ben oyunumda hierarchy panelinde bir prefab yokken oyunu başlattığımda karakter prefabının oluşmasını istiyorum nasıl yapılabilir

  34. osman diyor ki:

    merhaba kardeşim.öncelikle çok güzel bi siten var.tebrik ediyorum… bu butonlarla alakalı bişey sormak istiyorum..şimdi diyelimki ben zil sesleri, veya komik sesler diye bi program yapmak istedim.adam zil seslerine tek tek bakarken bitane zil sesini beğendi bunu telefonuna indirmek istedi. bunun yanına nasıl indir butonu koyabilirim. yani bunun kodu nasıl olur. teşekkürler şimdiden.

  35. nuri diyor ki:

    hocam kolay gelsin
    mesela elimizde bir top var.topun zıplaması ıcn buton yaptık.
    butona ne kadar basılırsa top o kadar yukarı zıplasın az basılırsa az cok basılırsa cok ve cok basmanında bir sınırı olsun istiyorum. yardımcı olabilirmisiniz tesekkürler.

    • nurii diyor ki:

      derslerinizdeki event trigger ı yaptım buna ek olarak normal tıklanma yı ekledım.event trıggerda cok.normal tıklanmada az deger girdim bu sefer her ikisini birden işleme aldı .bir türlü çözüm bulamadım.

    • yasirkula diyor ki:

      Yine PointerDown ve PointerUp kullanabilirsiniz. “zaman” adında bir float olur ve PointerDown’da değerini Time.time yaparsınız. PointerUp’ta ise “Time.time – zaman”ın değerine bakarsınız (bu değer, butona kaç saniye boyunca basılı tutulduğunu söyler); ona göre istediğiniz miktarda zıplarsınız.

  36. nuri diyor ki:

    hocam o zaman buton bırakıldıgında zıplama işlemini yapar.
    butona basıldıgı andan itibaren zıplattıramazmıyız

    • yasirkula diyor ki:

      Evet buton bırakıldığında zıplar. Sizin istediğiniz işlem nasıl yapılır bilmiyorum.

      • nuri diyor ki:

        hocam degişik kombinasyonlar yaparak istediğim gibi zıplattırdım.
        teşekkür ederim yardımınız için.ayrıca dersleriniz hepsi çok başarılı devamını dilerim:)

  37. nuri diyor ki:

    hocam bir sorum daha var
    2D bi karakter var elimizde herhangi bi objenin kenarına çarpınca karakter devriliyor.
    3 boyutluda rigidbody den freeze position/rotation kısmından ayarlıyabiliyorduk 2 boyutluda nasıl yapıcaz

  38. nuri diyor ki:

    hocam UI butona basınca zıplayan karakterim orantısız zıplıyor.normal yere temas edince zıpla dediğimde hep aynı düzeyde zıplıyor.ama butonda olmuyor
    yani bazen az bazen çok zıplıyor
    zıplama işini rigidbody.AddForce den yapıyorum.
    bu sorun nasıl çözülür. teşekkürler.

    • yasirkula diyor ki:

      Butona basınca zıplıyor diyorsunuz. O halde böyle bir sorun olmamalı, sebebini bilmiyorum.

      • nuri diyor ki:

        time.deltatime dan oluyormus sanıırm onu cıkarınca duzeldi
        bu time.deltatime olmasa ne değişirki?

      • nuri diyor ki:

        ayrıca hocam bu;
        time.timeScale
        time.fixedDeltaTime
        time.deltaTime

        ne işe yarıyor bu kodlar

      • yasirkula diyor ki:

        Time.deltaTime son iki frame arasında geçen saniyeyi döndürüyor ve değeri genelde oldukça ufak bir sayı oluyor.
        Time.fixedDeltaTime’ı bilmiyorum.
        Time.timeScale ise oyunun hızını değiştirmeye yarıyor.

  39. ahmetcankisactutan diyor ki:

    Merhaba Yasir Bey ilginç bi sorunla karşı karşıyayım..C# da değişken tanımlarken public ibaresine “Unexpected symbol “public” uyarısı alıyorum..Bir de start fonksiyonunda tanımladığım değişkene update fonksiyonunda ulaşamıyorum..Nedeni ne olabilir?Yardımcı olursanız sevinirim

    • yasirkula diyor ki:

      C#’ta değişken tanımlamak şu şekilde oluyor:

      public int degisken = 0;

      Yani “public var degisken : int = 0;” yazıyorsanız düzgün çalışmaz. Buna ilaveten, tüm script bir class’ın içerisinde olmalıdır. Yani eğer scriptin ismi Script ise kodun tamamı “public class Script : MonoBehaviour { // kod buraya geliyor }” ibaresi içerisinde yer almalıdır.

  40. Basay diyor ki:

    Ya bana bir yardımcı olun; sitedeki joystick te neyin Vector2 sini neye yapcam anlamadım bi yardım lütfen.

    • yasirkula diyor ki:

      Joystick sağa kıvrıldıkça Vector2’nin x değeri 0’dan 1’e yaklaşır, yukarı kıvrıldıkça Vector2’nin y değeri 0’dan 1’e yaklaşır. Sola veya aşağı kıvrıldıkça ise 0’dan -1’e yaklaşır. Bu değerleri nasıl kullanmak istediğiniz size kalmış birşey.

      • Basay diyor ki:

        ben hareket etsin birde etrafına baka bilsin istiyorum ve iki joystick yapmaya çalışıyorum ama yapamadım dediklerinizi yapıyorum bir türlü olmuyor; first personel character için olacak bu kontrol karakterin içinde herhangi bir şeyin olması filan gerek mi söyler misiniz?

      • yasirkula diyor ki:

        Bu dediğiniz karakter ve kamera hareket ettirme olayları oldukça karmaşık işlemler. Kusura bakmayın ama hiç bulaşmayacağım bu konuya; en iyi şansınız Youtube’ta karakter hareket ettirmekle alakalı video ders izlemek.

  41. Sefa DOĞAN diyor ki:

    İyi günler gerçekten çok yardımcı oldu fakat bir sorum var ben Uİ buton ile karakterimi ileri geri yaptırıyorum android tabanlı

    fakat butona bastığımda 1 frame ilerliyor halbuki basılı tuttuğum süre boyunca ilerlemesi lazım nasıl halledebilirim ?

    • yasirkula diyor ki:

      “Bir UI Elemanına Basılı Tutulduğu Sürece Yapılacak Şeyleri Belirlemek (Event Trigger Sistemi)” başlığını okuyabilirsiniz.

  42. fatmanur diyor ki:

    İyi günler. Ben unity3d de yeniyim. Unity web player tabanında hazırlamış oldugum bir projeyi birden fazla cihaza yüklemek ve her bir cihazı admin panelinden kontrol etmek istiyorum. Bunun yolu nedir?

    • yasirkula diyor ki:

      Sisteme giriş yapan kullanıcıların verilerini online olarak düzenlemek istiyorsanız aklıma gelen tek yol kullanıcı verilerini bir veritabanında tutmanız. Bu konuda tecrübem olmadığı için bunu nasıl yaparsınız bilemiyorum.

  43. osman diyor ki:

    Öncelikle bu müthiş çalışman her uygulamamda çok işime yaradı…Hocam merhabalar…Ben şimdi ekrana bir text yazdırdır. yanınada yukarı – aşağı ok koydum yukarı butona basarak ekrandaki text i bi sonraki yazıyı yazsın.aşağı ok butonuna bastığımda da bi önceki yazıya geri gelsin istiyorum.yani birçok yazıyı o butonlarla nasıl değiştirebilirim.scripti hakkında bişeyler söylermisiniz.teşekkürler.

    • yasirkula diyor ki:

      Content’i scroll etmekten bahsettiğiniz için aklıma gelen çözüm yolu Scroll Rect kullanmanız. Butonlara bastıkça scroll rect’in verticalNormalizedPosition’ını değiştirmeyi deneyebilirsiniz.

      • Can diyor ki:

        Sitenizde unity’de profiler ile ilgili bir ders verebilirmisiniz araştırdım oyun optimizasyonuymuş ama türkçe kaynak yok eğer vaktiniz olursa profiler ile ilgili bir ders yazabilirmisiniz ?😅

      • yasirkula diyor ki:

        Kendim de adam akıllı öğrenince ders yazabilirim, fikir için teşekkür ederim.

  44. Barış diyor ki:

    Butonlar düzgün bir şekilde çalışıyor ama sadece telefonlarda, tabletlerde butonlar aşırı büyük görünüyor başka butonlara yer kalmıyor.

    • yasirkula diyor ki:

      Ya anchorları düzgün yapmalı ya da “Arayüzün Her Çözünürlükte Aynı Görünmesini Sağlamak” başlığını okumalısınız. Arayüzü farklı çözünürlüklerde test etmek için direkt Game panelindeki sol üstte yer alan çözünürlük butonunu kullanabilirsiniz.

  45. Turan diyor ki:

    Kardeşim ellerine sağlık, Allah razı olsun. Çok sağlam paylaşım olmuş.

  46. Kursat diyor ki:

    Terimleri yabancı olarak tutmanız çok harika olmuş! Elinize sağlık!

  47. onur diyor ki:

    abi C# ta buton tanımlamak budeğilmi
    public Button[] buttons;

  48. İbrahim diyor ki:

    Gameobject ile Gui de yaptığımız alanla ilişkilendirmem lazım.Nasıl yapabilirim ?

  49. can diyor ki:

    Hocam elinize sağlık.
    benim sorum biraz farklı
    oyunu yaptım fakat farklı ekran çözünürlüklerine sahip telefonlarda denediğimde mesela bir telefonda solda bi obje gözükürken diğer telefonda o obje gözükmüyor,
    yani birinde daha geniş kamera ile diğerinde daha dar kamera açısı ile gösteriyor.
    bu uı ya da guı ile alakalı değil direk gameobjesinden bahsediyorum.
    bunu nasıl her çözünürlüklü telefona uygun hale getirebiliriz?
    Teşekkür ederim.

    • yasirkula diyor ki:

      Ekranların en/boy oranı (aspect ratio) farklı olduğundan bazı ekranlarda ekranın genişliği yeterli olmuyor. Ancak isterseniz şöyle bir kod deneyebilirsiniz (kameraya verilmeli):

      public float ekranGenislik = 10f;
      
      void Start()
      {
      	GetComponent<Camera>().orthographicSize = ekranGenislik / GetComponent<Camera>().aspect;
      }
      

      Kameranın genişliği istediğiniz gibi olana kadar “ekranGenislik” değişkenini değiştirin.

  50. can diyor ki:

    Teşekkür ederim sonuç olumlu oldu.
    Ayrıca şuda alternatif bir çözüm
    https://www.assetstore.unity3d.com/en/#!/content/59755

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Connecting to %s