UNITY İle Android’e Uygulama Geliştirmek – 1 – Dokunmatik Ekran Entegrasyonu

Yayınlandı: 17 Temmuz 2013 yasirkula tarafından Oyun Tasarımı, UNITY 3D içinde

GÜNCELLEME (01.07.2018): Kod C#’a çevrildi ve Input.touches değişkeni yerine Input.touchCount ve Input.GetTouch kullanıldı.

Yine ve yeniden merhaba,

Bu UNITY dersinde, Android için uygulama geliştirmenin temellerini öğreneceğiz. Dersin bu ilk parçasında dokunmatik ekranın nimetlerinden faydalanmayı görecek, ikinci derste ise telefonun hareket sensörünü kullanmayı öğreneceğiz (2. derse gitmek için tıklayın: https://yasirkula.com/2013/07/22/unity-ile-androide-uygulama-gelistirmek-2-telefon-sensorunu-kullanmak/). Bu derse başlamadan önce UNITY için Android SDK kurulumunu yapmış olmanız gerekiyor. Eğer yapmadıysanız şu dersimize göz atabilirsiniz: https://yasirkula.com/2013/07/17/unity-android-sdk-kurulumu-resimli-anlatim/

Hazırsanız touchscreen’e dalışı yapalım…

Şimdi, yapacağımız örnek uygulamadan bahsetmek istiyorum. Bu uygulamada ekranda bir küp olacak ve bu küp bizim dokunmatik ekranda tıkladığımız konuma ışınlanacak. Ayrıca bu küpün boyutlarını, ekranda elimizi sağa-sola ya da yukarı-aşağı kaydırarak değiştirebileceğiz. Bu uygulamayı yaparken öğreneceklerinizi kolaylıkla kendi uygulamalarınıza da uygulayabileceğinizi umuyorum.

Öncelikle UNITY’i açın ve yeni bir proje oluşturun. Main Camera‘yı (0, 0, -10) konumuna yerleştirin ve ardından yeni bir Cube GameObject oluşturup bu objenin Transform component‘indeki değerleri resetleyin. Şimdi yeni bir C# script oluşturup bu script’i küp objesine atayın. Son olarak, sahnede bir Directional Light oluşturun ki küpün hareketlerini rahatlıkla gözlemleyebilelim.

Aşama 1 : PC

Uygulamamızı Android’e yazmadan önce PC platformu için yazıp sonra Android’e convert etmeyi uygun gördüm. Bu yüzden öncelikle projeyi bilgisayar üzerinden test edecek, sonra birkaç ufak değişiklikle Android’e çevireceğiz.

İlk önce, küpün ekranda fare ile tıkladığımız yere ışınlanmasını sağlayalım. Bunun için Update() fonksiyonunu kullanmamız uygun olur. Scripti açın ve Update() fonksiyonuna şu kısacık kodu yazın:

if( Input.GetMouseButtonDown( 0 ) )
{
	transform.position = Camera.main.ScreenToWorldPoint( new Vector3( Input.mousePosition.x, Input.mousePosition.y, 10 ) );
}

Bu kod sayesinde eğer herhangi bir anda farenin sol tuşuna basılırsa, farenin ekrandaki konumu, Main Camera’nın mevcut pozisyon ve eğimine göre 3 boyutlu uzayda bir noktaya çevriliyor ve obje bu noktaya ışınlanıyor. Şimdi biraz daha detaylı açıklayayım:

Camera.main ibaresi, sahnedeki “MainCameratag‘ına sahip kameraya ulaşmak için kullanılır. Camera class’ının içerisinde ScreenToWorldPoint adında bir fonksiyon bulunmaktadır. Bu fonksiyonun parantezinin içine bir Vector3 değer girilir. Girilen bu Vector3’ün x ve y değerleri ekrandaki bir pikselin konumuna işaret etmelidir, bizim durumumuzda bu fare imlecinin ekrandaki konumunun x ve y koordinatlarına denk geliyor. Vector3’ün z değeri ise, 3 boyutlu uzaya çevrilecek noktanın kameradan kaç birim uzak olması gerektiğini belirtiyor, bunun değeri ise bizim örneğimizde 10. Yani Main Camera’nın z koordinatının -10’da olduğunu ele alırsak küp objemizin z değeri bundan 10 birim fazla olacak, yani 0 olacak. ScreenToWorldPoint fonksiyonu, içine girilen bu Vector3’ü alır ve bize 3 boyutlu uzayda bir nokta döndürür. Bu nokta döndürülürken hangi kameranın referans alınacağını ise en başta belirtmiştik zaten: Camera.main.

Şimdi de küpün boyutunun biz fareyi sürükledikçe değişmesini ayarlayalım. Bunun için script’in içinde şöyle değişiklik yapın:

Vector3 mouseEskiKonum;

void Update ()
{
	if( Input.GetMouseButtonDown( 0 ) )
	{
		transform.position = Camera.main.ScreenToWorldPoint( new Vector3( Input.mousePosition.x, Input.mousePosition.y, 10 ) );
		mouseEskiKonum = Input.mousePosition;
	}
	else if( Input.GetMouseButton( 0 ) )
	{
		transform.localScale += ( Input.mousePosition - mouseEskiKonum ) / 100;
		mouseEskiKonum = Input.mousePosition;
	}
}

Burada görüldüğü üzere, öncelikle mouseEskiKonum adında bir Vector3 değişken oluşturduk ve ekranda bir noktaya tıklandığında, bu değişkene fare imlecinin koordinatlarını atadık. Ardından Input.GetMouseButton(0) fonksiyonuyla, farenin sol tuşunun basılı olduğu her frame’de, objenin boyutunun (transform.localScale) fare imlecinin mevcut konumuyla eski konumu arasındaki farkın 1/100’ü kadar değişmesini sağladık. Neden 1/100? Çünkü ekran koordinatları piksellerle alakalı ve fareyi birazcık bile oynatsak ekranda epey piksel katedebiliriz. Ancak 3 boyutlu dünyada (World koordinatlarında) metrelerle işlem yapıyoruz ve 1 metrelik bir değişiklik bile küpün boyutunda ciddi değişikliklere yol açar. Bu yüzden her 100 piksellik oynamada küpün 1 metre büyümesini sağladık. Son olarak da, mouseEskiKonum değişkeninin değerini fare imlecinin güncel konumuna ayarladık.

Ve böylece ufak uygulamamızı PC için yazmış olduk. Şimdi sıra bunu Android’e uyarlamaya geldi!

Aşama 2 : Android

Uygulamayı Android’e çevirmeden önce, touchscreen ile alakalı önemli komutları açıklamak istiyorum.

Android’e uygulama geliştirirken, dokunmatik ekranla işlem yapmak için en aşina olmanız gereken iki komut, Input.GetTouch fonksiyonu ve Input.touchCount değişkeni. Bu komutlar ne işe yarar? Input.touchCount, ekrana dokunan parmak sayısını döndürürken, Input.GetTouch ise bu parmaklardan birisi hakkında detaylı bilgi döndürür. Peki bu detaylı bilgi ne türde depolanır? Vector3 mü? Transform mu? Hayır! Bu parmaklar çok daha gelişmiş bir tür olan Touch türünde depolanır.

Touch türünde depolanmakta olan bir parmak ile neler yapılabilir? Touch dediğim şey bir struct olup içerisinde çeşitli değişkenler barındırır. Mesela bunlardan biri position‘dır ve bu değişken, parmağın dokunmatik ekrandaki konumunu bir Vector2 olarak tutar. Bunun haricinde deltaPosition değişkeni de oldukça önemli olup, parmağın ekranda son frame’den itibaren yatay ve dikey eksende kaç piksel hareket ettiğini bir Vector2 olarak döndürür. O halde deltaPosition.x dediğimiz zaman, parmağın yatay eksende kaç piksel hareket ettiğini, deltaPosition.y dediğimiz zaman da parmağın dikey eksende kaç piksel hareket ettiğini bulmuş oluruz. Touch‘ın depoladığı bir başka önemli değişken ise phase değişkenidir. Bu değişken TouchPhase türündedir ve parmağın mevcut durumunu depolar. Daha açık konuşmak gerekirse, parmağın ekrana yeni mi dokunduğunu (TouchPhase.Began), yoksa ekranda hareket halinde olan bir parmak mı olduğunu (TouchPhase.Moved), ekranda hareketsiz bir şekilde basılı olarak duran bir parmak mı olduğunu (TouchPhase.Stationary) ya da ekrandan yeni kaldırılan bir parmak mı olduğunu (TouchPhase.Ended) depolar. Ekrana aynı anda beşten fazla parmağın dokunması gibi nadir olaylarda ise değeri TouchPhase.Canceled olur. Touch, bir başka önemli değişken daha depolar: fingerId. Bu değişken, ekrandaki o parmağa has bir int değeridir. Bu değişkenle ne yapılabilir? Örneğin oyununuzda sadece ekrandaki bir parmağı kaâle almak istiyor, ekrana sonradan dokunan parmakların hiçbir etki etmemesini istiyorsanız, o zaman bir değişkene o parmağın fingerId‘sini atayabilir ve ardından bir parmakla iş yaparken önce o parmağın fingerId‘sinin depoladığınız değişkene eşit olup olmadığına bakabilirsiniz.

Evet, dokunmatik ekranla ilgili önemli olan komutları böylece öğrenmiş olduk. Ne kadar az idi, değil mi! İşte bu yüzden UNITY ile Android’e uygulama geliştirmek aslında hiç de zor değil. Şimdi hazırsanız yarıda bırakmış olduğumuz örnek uygulamamızı Android’e transfer edelim.

Önce küpümüzü ekranda dokunduğumuz konuma ışınlandırmayı yapacağız. Bunun için bize gerekli olan şey ne? Ekrana dokunan bir parmağın (Touch) konumu. Peki bu Touch türündeki parmağa nasıl ulaşıyorduk? Evet, Input.GetTouch fonksiyonu ile. O halde Input.GetTouch ve Input.touchCount vasıtasıyla ekrandaki tüm Touch‘ların phase değişkenine bakmalı ve, eğer parmak ekrana yeni dokunmuşsa (TouchPhase.Began) küpü parmağın ekrandaki konumuna (position) ışınlamalıyız. Bunun için küp objesine atadığınız scripti açın ve Update() fonksiyonunu şöyle değiştirin:

int parmakSayisi = Input.touchCount;

for( int i = 0; i < parmakSayisi; i++ )
{
	Touch parmak = Input.GetTouch( i );
	
	if( parmak.phase == TouchPhase.Began )
	{
		transform.position = Camera.main.ScreenToWorldPoint( new Vector3( parmak.position.x, parmak.position.y, 10 ) );
	}
}

Sanıyorum bu kodu açıklamaya gerek yok, çünkü neyi niçin yaptığımızı zaten yukarıda öğrendik. Burada, PC için olan kodu Android’e uyarlamanın ne kadar kolay olduğuna dikkat çekmek istiyorum. Sadece birkaç satırla uygulamamıza Android desteği sunduk. Uygulamanın ikinci aşamasını Android’e aktarmak da bir bu kadar kolay. Tek yapmamız gereken, for döngüsünün içini şu hale getirmek:

for( int i = 0; i < parmakSayisi; i++ )
{
	Touch parmak = Input.GetTouch( i );
	
	if( parmak.phase == TouchPhase.Began )
	{
		transform.position = Camera.main.ScreenToWorldPoint( new Vector3( parmak.position.x, parmak.position.y, 10 ) );
	}
	else if( parmak.phase == TouchPhase.Moved )
	{
		transform.localScale += (Vector3) parmak.deltaPosition / 100;
	}
}

Gördüğünüz gibi içeriye bir “else if” ekledik ve eğer parmak ekranda hareket ettirilmişse (TouchPhase.Moved), küp objesinin boyutlarını değiştirdik. Bu esnada parmakEskiKonum gibi gereksiz bir değişkene de ihtiyacımız olmadı, çünkü hatırlayacağınız gibi, “Touch” türü içerisinde zaten bir deltaPosition barındırıyor! Yine hatırlayacağınız üzere, bu deltaPosition bir Vector3 değil ama bir Vector2. Ancak transform.localScale değişkeni bir Vector3 ve bu yüzden transform.localScale‘e bir Vector2 ekleyemezdik. Bunu çözmek için, parmak.deltaPosition‘ı bir Vector3‘e dönüştürdük (typecast).

Evet, bitti! Buraya kadar gelmişseniz bir Android developer olma yolunda büyük bir basamak atladığınızı söyleyebilirim. Şimdi dilerseniz uygulamayı Android’e Build edip telefonunuzda test edebilirsiniz. Peki şimdi ne yapmalı? Öğrendiklerinizi pekiştirmek için niçin kendi başınıza basit bir Android oyunu yapmıyorsunuz? Heyecan verici!

Umarım faydalı olmuştur, dersin ikinci kısmında görüşmek üzere!

NOT: if( GUI.Button( blabla ) ) şeklinde oluşturduğunuz tüm GUI elemanları aynı zamanda otomatik olarak dokunmatik ekran desteğine de sahip. Yani onlar için ekstra kod yazmanız gerekmiyor.

yorum
  1. qqqqqq dedi ki:

    Hocam touchScreen.current nedir açıklayabilir misiniz ?

  2. Ahmet dedi ki:

    Hocam agario benzeri bir oyun yapıyorum. Karakterimi input mouse position ile hareket ettiriyorum. Sahnemin sağ alt tarafında bir buton var. O butona basınca karakterim ateş ediyor. Yalnız şöyle bir sorunum var. Diyelim ki karakterim yukarı doğru gidiyor. Ateş etme tuşuna basınca karakterim yukarı gitmeyi bırakıp, sağ alt tarafa butonun olduğu yere doğru gidiyor. “Benim istediğim olay ateş etme tuşuna basınca fare kordinatını yok sayalım ve aynı zamanda karakterim yukarı gitmeye devam etsin.” Bunu nasıl yapabiliriz. Hareket scripti şu şekilde.

    void Update()
    {
    Vector3 Target = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    Target.z = transform.position.z;
    transform.position = Vector3.MoveTowards(transform.position, Target, hız * Time.deltaTime);
    }

    • yasirkula dedi ki:

      Ekrana tıklandığı anda EventSystem.current.IsPointerOverGameObject fonksiyonunu çağırmanız lazım (mobil cihazlarda bu fonksiyona parametre olarak, tıklayan parmağın Touch.fingerId değerini vermek gerekiyor diye biliyorum). Eğer bu fonksiyon true döndürüyorsa, parmak bir UI elemanı üzerindedir ve bu durumda parmak ekrandan kalkana kadar o parmağın input’unu yoksaymanız lazım.

  3. enes dedi ki:

    hocam if (!EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId)) koduyla onmousedownda uı a basınca gameobjeye tıklamasını onlemeye calısıyorum ama olmuyor ne yapabılırım

    • yasirkula dedi ki:

      Kodunuz doğru duruyor. Editörde test ederken veya 2. parmak ile tıklarken mi çalışmıyor?

    • enes dedi ki:

      Hocam çözdüm belki bu problemi başka biri daha yaşarsa diye çözümüm şöyle On mousedown yerine on mouse up kullandım çözüldü olay verdiğiniz cevap için teşekkür ederim yeni gördüm kusura bakmayın hocam

  4. emrullo dedi ki:

    Merhaba hocam ben bir oyun yapıyorum oyunda kareketerimiz ileriye doğru gidiyor karşısına engeller çıktıkça yukarı veya aşağı gitmesini istiyorum ama yukarı tıkladığımda yukarıda ilerlemeye devam etsin aşağıya bastığımdıda aynı şekilde aşağıda sağa dogru ilerlesin bunun için kod yazbilirmisin. 2D oyun yapıyorum teşekkürler…

    • yasirkula dedi ki:

      Şuradaki “Unity’e yeni başladım ve daha hiçbir bilgim yok. Sizce nasıl bir yol izlemeliyim?” başlığında yer alan derslere baktıktan sonra, bu kodu ve ileride ihtiyacınız olabilecek başka kodları kendi başınıza da yazabilecek donanıma sahip olacağınıza inanıyorum: https://yasirkula.com/2014/09/05/unity-sikca-sorulan-sorular-s-s-s/

      • emrullo dedi ki:

        Teşekkürler hocamda ben sadece yön için bir kod satırı istedim yardımlarınızı bekliyorum…

      • yasirkula dedi ki:

        Şuna benzer bir şey yapabilirsiniz:

        if(Input.GetMouseButtonDown(0))
        {
        Vector3 konum = karakter.transform.position;
        if(Input.mousePosition.y > Screen.height / 2)
        konum.y = 5.0f; // Üst kenarın y koordinatı
        else
        konum.y = -5.0f; // Alt kenarın y koordinatı

        karakter.transform.position = konum;
        }

  5. Kerim GÖK dedi ki:

    Ağabey bir kod yazdım ışınlama kodu. Kod çalışıyor ama ışınlanan obje takılıyor.
    Kod şu :
    void OnTriggerEnter2D(Collider2D col)
    {
    if(col.name == “ScoreObject”)
    {
    ball.position = firstPosition.position;
    score++;
    scoreText.text = score.ToString();
    }
    }

    Nerede hata yaptım veya yaptım mı ?

    • yasirkula dedi ki:

      Kodunuzda bir hata göremedim. Objenin takılmasından kastınız nedir? Obje olduğu yerde sapıtıyor mu veya eskiden ileri geri hareket ederken artık hareket etmiyor mu?

  6. Kerim GÖK dedi ki:

    Ağabey merhaba bir android oyun yapıyorum. Oyun için brick breaker deki gibi bir sütunun kaydırdığımızda x ekseninde yer değiştirmesi lazım. Onu nasıl yapabilirim?

    • yasirkula dedi ki:

      Derste gösterdiğim kodlardan faydalanarak, sütunu Update fonksiyonunda x ekseninde şu kadar transform.Translate edebilirsiniz:

      PC için: (Input.mousePosition – mouseEskiKonum).x (ör: sutunObjesi.transform.Translate((Input.mousePosition - mouseEskiKonum).x * 0.5f, 0f, 0f);)
      Android için: parmak.deltaPosition.x

      • Kerim GÖK dedi ki:

        Ağabey hepsi tamam lakin bunu bir türlü beceremiyorum tam olarak kodu yazar mısın yukarıdaki gibi?

      • yasirkula dedi ki:

        public Transform sutunObjesi;
        public float hiz = 0.5f;
        private Vector2 mouseEskiKonum;

        void Start()
        {
        mouseEskiKonum = Input.mousePosition;
        }

        void Update()
        {
        sutunObjesi.Translate( ( Input.mousePosition – mouseEskiKonum ).x * hiz, 0f, 0f );
        mouseEskiKonum = Input.mousePosition;
        }

  7. Faruk Öztürk dedi ki:

    Hocam ben 2D bir oyun yapıyorum ve dokunduğum objeyi yok etmek istiyorum nasıl yapabilirim?

  8. AliHD dedi ki:

    Hocam merhaba,
    Aslında sorumu yanlış sordum yani sormak istediğim şu şekilde diyelim ki sahnede iki tane küpvar birinci küpe tıkladığım zaman debug.log da ali yazsın ikinci küpe tıkladığımda mehmet yazsın bunun kodunu nasıl yazmalıyım

    • AliHD dedi ki:

      Hocam çok teşekkür ederim gerek kalmadı verdiğiniz kod ile halledebildim teşekkürler

  9. AliHD dedi ki:

    Hocam merhaba,

    Parmağımızı dokunmatik ekranda sürükleyerek kamerayı harelet ettirmek için nasıl bir kod yazılmalıdır.

    • yasirkula dedi ki:

      kamera.transform.Rotate( parmak.deltaPosition.y, parmak.deltaPosition.x, 0f ); gibi bir kod kullanabilirsiniz.

      • AliHD dedi ki:

        Hocam Merhaba,
        Sahnede 3 tane 3d nesne olsun bu küplerin biri kırmızı birsi sarı ve yeşil olsun ben tek bir scripte buda kameranın içine atılmış bir script olsun bu küplerden birine dokunduğumuz zaman rengi debug.log olarak nasıl yazdırabiliriz. Yani koda nesneleri tanıtıp dokunma fonksiyonunu nasıl ekleyebiliriz.

      • yasirkula dedi ki:

        Input.GetMouseButtonDown(0) ise Physics.Raycast yapıp hangi objeye dokunduğunuzu öyle tespit etmeniz lazım:

        private void Update()
        {
        	if( Input.GetMouseButtonDown( 0 ) )
        	{
        		RaycastHit hit;
        		if( Physics.Raycast( GetComponent<Camera>().ScreenPointToRay( Input.mousePosition ), out hit ) )
        		{
        			Renderer r = hit.transform.GetComponent<Renderer>();
        			if( r != null )
        				Debug.Log( r.sharedMaterial.color );
        		}
        	}
        }
        
  10. Furkan dedi ki:

    hocam fırlatılacak objeyi spawnlamak için
    Vector2 starPos, endPos, direction;
    float touchTimeStart, touchTimeFinish, timeInternal;

    [SerializeField]
    float throwForceInXandY = 1f;

    [SerializeField]
    float throwForceInZ = 50f;

    Rigidbody rb;
    public GameObject[] obje;
    float a = -0.002f;
    float b = -1.568f;
    float c = -2.836f;
    void Start()
    {
    rb = GetComponent();
    }

    void Update()
    {
    if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
    {
    touchTimeStart = Time.time;
    starPos = Input.GetTouch(0).position;

    }

    if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Ended)
    {

    touchTimeFinish = Time.time;
    timeInternal = touchTimeFinish – touchTimeStart;

    endPos = Input.GetTouch(0).position;

    direction = starPos – endPos;
    if (direction.magnitude < 10f) // Eğer parmak 10 pikselden az hareket ettiyse bir şey yapma
    return;
    if (timeInternal < 0.1f) // Eğer parmak ekranda 0.1 saniyeden kısa süre durduysa bir şey yapma
    return;
    rb.isKinematic = false;
    rb.AddForce(-direction.x * throwForceInXandY, -direction.y * throwForceInXandY, throwForceInZ / timeInternal);

    Destroy(gameObject, 3f);
    Vector3 konum = new Vector3(a, b, c);
    Instantiate(obje[0], konum, Quaternion.identity);

    }

    }

    böyle bir kod yazdım ama obje yok olduktan sonra spawnlanmıyor yani nerde hata yaptım birde bi soru daha soracağım hadi bunu istediğimiz gibi kameranın önünde spawnladık diyelim kamera hareket edince hareket ettiği yere nasıl spawnlıyacağız

    • yasirkula dedi ki:

      obje array’inize projenizdeki prefab’ları değer olarak verdiğinizi varsayıyorum; oraya sahnenizdeki bir objeyi değer olarak vermeyin çünkü o obje Destroy olursa Instantiate çalışmaz.

      Objenin hep kameranın önünde spawn olması için, boş bir obje (Empty) oluşturun, bunu sürükle-bırak ile kameranın alt objesi (child objesi) yapın ve istediğiniz gibi konumlandırın. Script’inizde bu objeyi “public Transform spawnNoktasi;” değişkeninde tutun ve Instantiate’te konum olarak spawnNoktasi.position yazın.

      • Furkan dedi ki:

        projemdeki prefab’ları değer olarak vermeden Instantiate komutunu nasıl çalıştırırım?

      • yasirkula dedi ki:

        Instantiate’in ilk parametresini null bir obje veremezsiniz, yani obje array’inin içi boşsa kodunuz çalışmaz.

      • Furkan dedi ki:

        hocam kontrol scripti oluşturdum oyunumdaki olayları kontrol ediyor birde top objem var kontrol scriptine top destroy olduktan sonra spawlanmasını istiyorum bunu kodda nasıl yazarım

      • yasirkula dedi ki:

        Topu sahnenizden sürükle-bırak ile Project paneline bırakınca bir prefab oluşacak. Instantiate’te bu prefab’ı kullanabilirsiniz. Veya daha iyisi, topu Destroy ettikten sonra yeniden spawn etmek yerine hiç Destroy etmeyin, direkt transform.position’ını değiştirin. Eğer top hareket halinde ise rb.isKinematic=true; gibi bir kodla Rigidbody’sini kinematic yapın.

  11. Furkan dedi ki:

    hocam merhaba ben topu fırlatan kodu yazabildim ama kamera hareket edince topunda kamerayla hareket etmesini istiyorum birde fırlattıktan 3sn sonra topun yok olup yeni bir top spawnlamasını istiyorum bide top 30dan fazla spawnlanırsa oyun bitsin istiyorum yani 30 top hakkı olacak bunu nasıl kodlayabilirim

    • yasirkula dedi ki:

      Topu kameranın child objesi yaparsanız kamera ile hareket eder. 3 saniye sonra bir fonksiyon çağırmak için Invoke(“FonksiyonIsmi”, 3f); fonksiyonunu çağırabilirsiniz. Ardından “void FonksiyonIsmi()” şeklinde bir fonksiyon tanımlayıp içinde topu yok edip yeni bir top spawnlayabilirsiniz. Bir de int değişkeniniz olsun ve spawnlanan top sayısını tutsun, yani her spawn’da 1 artsın. Eğer değeri 30 olursa game over olsun.

      • Furkan dedi ki:

        hocam fırlatıldıktan sonra silinecek bunu nasıl kodlayacağım
        Vector2 starPos, endPos, direction;
        float touchTimeStart, touchTimeFinish, timeInternal;

        [SerializeField]
        float throwForceInXandY = 1f;

        [SerializeField]
        float throwForceInZ = 50f;

        Rigidbody rb;

        void Start()
        {
        rb = GetComponent();
        }

        void Update()
        {
        if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
        {
        touchTimeStart = Time.time;
        starPos = Input.GetTouch(0).position;
        }

        if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Ended)
        {

        touchTimeFinish = Time.time;
        timeInternal = touchTimeFinish – touchTimeStart;

        endPos = Input.GetTouch(0).position;

        direction = starPos – endPos;
        rb.isKinematic = false;
        rb.AddForce(-direction.x * throwForceInXandY, -direction.y * throwForceInXandY, throwForceInZ / timeInternal);

        Destroy(gameObject, 3f);
        }

      • Furkan dedi ki:

        pardon hocam yanlış sordum fırlatıyorum ama dokunarak ta fırlıyor yani hedefe dokununca top kurşun gibi uçuyor ama topu normal atınca yani istediğim gibi sürterek oluyor ama hedefe dokununca gitmesini nasıl engellerim

      • yasirkula dedi ki:

        “direction = starPos – endPos;” satırının altına şunu ekleyebilirsiniz:

        if(direction.magnitude < 10f) // Eğer parmak 10 pikselden az hareket ettiyse bir şey yapma
        return;

        if(timeInternal < 0.1f) // Eğer parmak ekranda 0.1 saniyeden kısa süre durduysa bir şey yapma
        return;

  12. furkan dedi ki:

    hocam sizin burdaki yazdığınız kod da da bunlar kullanılmış ama istediğim gibi hareket etmiyor ben ekrana parmagım sürtünce topun sürtüğüm konuma gitmesini istiyorum ama top dokunduğum hedefe gidiyor .

    • yasirkula dedi ki:

      Evet bahsettiğim fonksiyonlardan faydalanarak kodu kendi başınıza istediğiniz şekilde yazmanız lazım.

      • Furkan dedi ki:

        hocam 2 gündür dediğiniz fonksiyonları tekrar tekrar denedim internette örnek kodları fln araştırma yaptım ama bir türlü topu dokunarak fırlatamadım?

      • yasirkula dedi ki:

        Topun Rigidbody’sinin velocity’sini ayarlayabilirsiniz. Bu bir Vector3 alır. Bu Vector3’ün ise x değeri, parmağın sağa-sola ne kadar kaydığı ile doğru orantılı olurken y ve z değerleri ise parmağın yukarı ne kadar kaydığı ile doğru orantılı olur. Eğer parmak aşağı kaydıysa bir şey yapmayabilirsiniz. Örneğin parmağın yatay kayma miktarını parmakX ve dikey kayma miktarını parmakY’de tutuyorsanız:

        GetComponent<Rigidbody>().velocity = new Vector3( parmakX * 2.5f, parmakY * 1.5f, parmakY * 2.5f );

  13. Furkan dedi ki:

    hocam merhaba ben hedef vurmaya dayalı bir oyun yapıyorum mesela beyzbol topunu atmak istediğimiz yere ve uzaklığa göre nasıl kodlarız aynı şekilde yavaş atmak veya hızlı atmayı nasıl kodlarız kısaca “Hit ve knock down” oyunundaki gibi nasıl yaparız

    • yasirkula dedi ki:

      Topa şuna benzer bir script verebilirsiniz:

      using UnityEngine;
      
      public class Firlatici : MonoBehaviour 
      {
      	private Camera kamera;
      	private Rigidbody rb;
      
      	public float hiz = 10f;
      
      	private void Start()
      	{
      		kamera = Camera.main;
      		rb = GetComponent<Rigidbody>();
      
      		rb.drag = 0f;
      		rb.angularDrag = 0f;
      		rb.useGravity = true;
      		rb.isKinematic = true;
      	}
      
      	private void Update()
      	{
      		if( Input.GetMouseButtonDown( 0 ) )
      		{
      			Ray ray = kamera.ScreenPointToRay( Input.mousePosition );
      			RaycastHit hit;
      
      			if( Physics.Raycast( ray, out hit ) )
      			{
      				Vector3 hedefKonum = hit.point + hit.normal * transform.localScale.x * 0.5f;
      				Vector3 mevcutKonum = transform.position;
      				Vector3 yon = hedefKonum - mevcutKonum;
      
      				float sure = new Vector3( yon.x, 0f, yon.z ).magnitude / hiz;
      				float dikeyHiz = yon.y / sure - Physics.gravity.y * sure * 0.5f;
      
      				Vector3 hareket = new Vector3( yon.x, 0f, yon.z ).normalized * hiz;
      				hareket.y = dikeyHiz;
      
      				rb.isKinematic = false;
      				rb.velocity = hareket;
      			}
      		}
      	}
      }
      
      • Furkan Onur dedi ki:

        Hocam sağolun şuan evde değilim ama deneyeceğim bir sorum daha olacak özür dilerim çok yoruyorum bunu monil olarak yapacagız ya bunu denemek için illa mobil apksini yapip mobilde mi denemem lazım yoksa bilgisayarda çalışır mı bu kod

      • yasirkula dedi ki:

        Bilgisayarda da çalışır. Kamerayı Raycast atmak için kullanıyoruz, yeri değişince sıkıntı olmamalı.

      • Furkan Onur dedi ki:

        Birde bu kodda kamerayla ne işimiz var oyunum levele dayalı olmayacağı için ilerleyen scorlarda kameranın yerini değiştireceğim sıkıntı olur mu? Yardımınız için teşekkür ederim

    • Furkan dedi ki:

      hocam kodu denedim fırlatacağımız obje illa top olamaycak biçimsiz küp gibi objeleri de fırlatacağım ama sıkıntı şu objeyi fırlatırken üst tarafa doğru kaydırınca öne doğru gidiyor objenin ortasına fln fareyle kaydırınca veya dokununca top geriye yukarı doğru uçuyor

      • yasirkula dedi ki:

        Physics.Raycast’in içerisine şunu ekleyebilirsiniz:

        if(hit.rigidbody == rb)
        return;

      • Furkan dedi ki:

        hocam topu fırlatıyorum ama geriye doğru hedefler önde top geriye fırlıyor

      • Furkan dedi ki:

        birde hocam bir objeyi istediğim noktada durmasını istiyorum hareket ettirdim ama durmuyor
        hareket ettirdiğim kod;
        transform.position -= transform.forward * hız * Time.fixedDeltaTime;

      • Furkan dedi ki:

        hocam Unity DOTween sayesinde istediğim gibi hareket ettirdim ama ben örneğin score 10 olunca hareket etmesini istiyorum bunu if olarak yazınca score adında bir değişken bulunamadı diyor ben skor değişkenini başka bir scripte yazdım o scripten skora nasıl ulaşırım.

      • yasirkula dedi ki:

        En basit yolu, skoru “public static int skor;” şeklinde tanımlayabilirsiniz. Bu durumda skora herhangi bir script’ten “SkorScripti.skor” şeklinde erişebilirsiniz.

      • Furkan Onur dedi ki:

        Hocam sağolun oldu ama bu hedefe atılan topu yapamadım sizin gösterdiğiniz kod hedefe tıklıyınca hedefe dogru gidiyor boyle oyun cok basit oluyor ben kendimiz firlatacagimiz birşey yapmak istiyorum mesela topu hizli ve yukarı dogru bir şekilde ekranda haraket ettirince yukaridaki hedefe yavaş bi şekilde haraket ettirince aşşağıdaki hedefe gitmesinu istiyorum ve birde bunu spawnlıyorum mesela yere fuştu yerdeki coliedera çarpinca tekrar o noktada spawnlaniyor ama oyunda kamera hareket ediyor bu sefer firlatacagim obje haraket etmiyor

      • yasirkula dedi ki:

        Input.GetMouseButtonDown(0): ekrana dokununca veya farenin sol tuşuna basınca true döndürür.
        Input.GetMouseButtonUp(0): ekrandan parmağı kaldırınca veya farenin sol tuşunu bırakınca true döndürür.
        Input.mousePosition: farenin/parmağın konumunu döndürür.
        Time.realtimeSinceStartup: oyun başladıktan itibaren kaç saniye geçtiğini döndürür.

        Bu fonksiyonlardan faydalanarak ekrana ne zaman dokunulduğunu, ne zaman parmağın ekrandan çekildiğini, kaç saniye boyunca ekrana basılı tutulduğunu ve farenin kaç piksel hareket ettirildiğini hesaplayabilirsiniz. Bu değerlere göre de istediğiniz gibi topa güç uygulayabilirsiniz.

  14. Bugra dedi ki:

    Hocam merhaba. 2D bir tank oyunu yapıyorum. Tank ilerleyip düşmanları yok edecek. Fakat yatay eksende düşen bir ateş etme yolu bulamadım. Mesela tank yukarı ateş edeceği zaman namlusu yukarı kalkacak ve ivmeli bir hareket yaparak bombeli bir şekilde mermi ilerleyip düşecek. Bu sırada merminin rotasyonununda eğilmesi gerekiyor. Yani şöyle söyleyeyim Angry Birds oyunundaki kuşları benim tank oyunundaki mermiler olarak düşünürsek ben atış yaptığım yere göre namlu belli bir açıya gelecek ve vurmak istediğim yere bombeli bir atış yapacak. Bu sırada mermi de düşerken mesela düz bir şekilde değilde eğilerek düşecek. Bu atışı da ekranda tıkladığım yere göre yapsın istiyorum. Bunu nasıl yapabilirim? Araştırıyorum ivmeli atış falan diye ama hiç bulamadım. Yardımcı olabilir misiniz?

    • yasirkula dedi ki:

      Mermiye Rigidbody2D verirseniz, mermi yerçekimi etkisi ile otomatik olarak aşağı düşmeye başlar. Mermiyi ilk başta yukarıya doğru fırlatmak için de mermiRigidbody.velocity = mermininGitmesiniIstediginizYon; kodunu kullanabilirsiniz.

      Merminin rotasyonunu ayarlamak için ise önce Rigidbody2D’nin Constraints’inden Free Rotation Z’yi işaretleyin. Ardından şuna benzer bir kod yazın: mermiRigidbody.transform.localEulerAngles = new Vector3(0, 0, Vector2.SignedAngle(Vector2.right, mermiRigidbody.velocity));

      Ayrıca dediğiniz gibi “unity angry birds tutorial” şeklinde arama yaparak da konuyla alakalı yazılı/video dersler bulabilirsiniz.

      • Buğra dedi ki:

        Hocam teşekkür ederim cevabınız için. Eksik olmayın. Angry Birds de gücü yay gerilimi gibi bir mekanizma veriyor sanırım. Benim oyunumda yay falan olmayacağı için nasıl olacak onu tam kestiremedim. Bu dediğiniz yönteme bir bakayım biraz araştırayım. İşin içinden çıkamazsam tekrar size yazacağım. Sağ olun.

  15. Hakan Güler dedi ki:

    Tek ve basit bir soru,
    Android Studio ile yapabildiklerimizi unity ile yapabilir miyiz? Yani oyun değil de normal uygulama geliştirmek için unity tercih etmek ahmaklık mı olur sizce?

    • yasirkula dedi ki:

      Eğer 3 boyutlu bir içerik kullanmayacaksanız Android Studio kullanmanız daha mantıklı çünkü uygulamanın boyutu daha küçük olacak, uygulama daha hızlı açılacak/çalışacak, daha az RAM yiyecek ve cihazı daha az ısıtacaktır.

  16. hakan dedi ki:

    bunu unity kendi roll a ball a nasıl ekleyebilirim

    • yasirkula dedi ki:

      Şunun gibi olabilir:

      float moveHorizontal = Input.GetAxis (“Horizontal”);
      float moveVertical = Input.GetAxis (“Vertical”);

      if (Input.touchCount > 0)
      {
      Touch parmak = Input.GetTouch (0);

      moveHorizontal = parmak.deltaPosition.x;
      moveVertical = parmak.deltaPosition.y;
      }

Cevap Yazın

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.