UNITY – OnMouseDown Fonksiyonunu Android’e Uyarlamak

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

GÜNCELLEME (18.06.2017): Yazı Unity’nin son versiyonuna uygun olarak güncellendi ve kodlar C#’a çevrildi.

NOT: Artık OnMouseDown fonksiyonlarını mobile uyarlarken, bu dersteki kodu kullanmak yerine, şu dersi incelemenizi öneririm: https://yasirkula.com/2020/03/21/unity-eventsystem-ile-multiplatform-mouse-parmak-inputu-almak/

Tekrar merhaba,

Bu derste Android için yaptığınız Unity oyunlarında bir objeye parmak ile dokunulup dokunulmadığını test etmenin yöntemini göstereceğim, yani bir başka deyişle PC’deki OnMouseDown fonksiyonunu Android’de nasıl multi-touch bir şekilde çalıştıracağınızı göstereceğim. Eğer oyununuz multi-touch gerektirmiyorsa o zaman bu derse ihtiyacınız yok; scriptlerinizde direkt OnMouseDown kullanabilirsiniz. Bu fonksiyon Unity tarafından otomatik olarak çağrılır ancak maalesef multi-touch desteklemez.

Dersin ilham kaynağı için tıklayın: http://wiki.unity3d.com/index.php?title=OnMouseDown

Bu işlemi yapmak için Raycast kullanacağız. Yani kameranın merkezinden başlayan ve ekranda tıkladığımız koordinat yönünde olan sonsuz uzunlukta bir ışın yollayacağız ve eğer bu ışın bir obje ile temas ederse anlayacağız ki parmağımızla dokunduğumuz objeyi bulduk. Ardından (eğer varsa) o objedeki MouseDown fonksiyonunu çağıracağız. Dikkat edin: MouseDown fonksiyonunu çağırıyoruz, OnMouseDown fonksiyonunu değil! Aksi taktirde dokunduğumuz bir objedeki OnMouseDown fonksiyonu hem bizim tarafımızdan hem de Unity tarafından çağrılabileceğinden fonksiyonu istemeden iki kere çalıştırabiliriz.

OnMouseDownMultitouch isminde yeni bir C# scripti oluşturup scripti Main Camera‘ya atın ve içeriğini şöyle düzenleyin (bu script hem PC’de hem de mobil cihazlarda çalışır, tek yapmanız gereken scriptlerinizdeki OnMouseDown fonksiyonlarını MouseDown’a çevirmek):

using UnityEngine;
 
public class OnMouseDownMultitouch : MonoBehaviour
{
	void Update()
	{
		Camera camera = Camera.main;
		RaycastHit hit;
 
		if( camera == null )
			return;
 
#if UNITY_EDITOR || UNITY_STANDALONE || UNITY_WEBGL
		// PC için kod (mouse)
 
		if( Input.GetMouseButtonDown( 0 ) )
		{
			if( Physics.Raycast( camera.ScreenPointToRay( Input.mousePosition ), out hit ) )
				hit.transform.gameObject.SendMessage( "MouseDown", SendMessageOptions.DontRequireReceiver );
		}
#else
		// Mobil cihazlar için kod (multi-touch)
 
		// Ekranda basılı olan tüm parmaklara bak
		for( int i = 0; i < Input.touchCount; i++ )
		{
			Touch parmak = Input.GetTouch( i );
			if( parmak.phase == TouchPhase.Began )
			{
				// Eğer bir parmak ekrana daha yeni basılmışsa o noktada bir Raycasting yaparak herhangi bir objeye tıklanıp tıklanmadığına bak
				if( Physics.Raycast( camera.ScreenPointToRay( parmak.position ), out hit ) )
					hit.transform.gameObject.SendMessage( "MouseDown", SendMessageOptions.DontRequireReceiver );
			}
		}
#endif
	}
}

Kodumuzu biraz daha geliştirerek OnMouseDrag ve OnMouseUp fonksiyonlarına da destek verebiliriz (yalnız yukarıda belirttiğim sebepten ötürü bizim durumumuzda MouseDrag ve MouseUp fonksiyonları çağrılacak):

using UnityEngine;
using System.Collections.Generic;
 
public class OnMouseDownMultitouch : MonoBehaviour
{
#if UNITY_EDITOR || UNITY_STANDALONE || UNITY_WEBGL
	private GameObject dokunulanObje = null;
#else
	private readonly Dictionary<int, GameObject> dokunulanObjeler = new Dictionary<int, GameObject>();
#endif
 
	void Update()
	{
		Camera camera = Camera.main;
		RaycastHit hit;
 
		if( camera == null )
			return;
 
#if UNITY_EDITOR || UNITY_STANDALONE || UNITY_WEBGL
		// PC için kod (mouse)
 
		if( Input.GetMouseButtonDown( 0 ) )
		{
			if( Physics.Raycast( camera.ScreenPointToRay( Input.mousePosition ), out hit ) )
			{
				dokunulanObje = hit.transform.gameObject;
				dokunulanObje.SendMessage( "MouseDown", SendMessageOptions.DontRequireReceiver );
			}
		}
		else if( Input.GetMouseButton( 0 ) )
		{
			if( dokunulanObje != null && !dokunulanObje.Equals( null ) )
				dokunulanObje.SendMessage( "MouseDrag", SendMessageOptions.DontRequireReceiver );
		}
		else if( Input.GetMouseButtonUp( 0 ) )
		{
			if( dokunulanObje != null && !dokunulanObje.Equals( null ) )
				dokunulanObje.SendMessage( "MouseUp", SendMessageOptions.DontRequireReceiver );
		}
#else
		// Mobil cihazlar için kod (multi-touch)
 
		// Ekranda basılı olan tüm parmaklara bak
		for( int i = 0; i < Input.touchCount; i++ )
		{
			Touch parmak = Input.GetTouch( i );
			if( parmak.phase == TouchPhase.Began )
			{
				// Eğer bir parmak ekrana daha yeni basılmışsa o noktada bir Raycasting yaparak herhangi bir objeye tıklanıp tıklanmadığına bak
				if( Physics.Raycast( camera.ScreenPointToRay( parmak.position ), out hit ) )
				{
					GameObject obje = hit.transform.gameObject;
					dokunulanObjeler[parmak.fingerId] = obje;
					obje.SendMessage( "MouseDown", SendMessageOptions.DontRequireReceiver );
				}
			}
			else if( parmak.phase == TouchPhase.Ended || parmak.phase == TouchPhase.Canceled )
			{
				// Eğer bir parmak ekrandan çekilirse ve bu parmak ekrana ilk dokunduğunda bir objeye tıklamışsa o obje için MouseUp fonksiyonunu çağır
				GameObject obje;
				if( dokunulanObjeler.TryGetValue( parmak.fingerId, out obje ) )
				{
					// Parmağın dokunulduğu obje yok edilmemişse
					if( obje != null && !obje.Equals( null ) )
						obje.SendMessage( "MouseUp", SendMessageOptions.DontRequireReceiver );
				}
			}
			else
			{
				// Eğer bir parmak ekranda basılı durumdaysa ve bu parmak ekrana ilk dokunduğunda bir objeye tıklamışsa o objenin MouseDrag fonksiyonunu çağır
				GameObject obje;
				if( dokunulanObjeler.TryGetValue( parmak.fingerId, out obje ) )
				{
					// Parmağın dokunulduğu obje yok edilmemişse
					if( obje != null && !obje.Equals( null ) )
						obje.SendMessage( "MouseDrag", SendMessageOptions.DontRequireReceiver );
				}
			}
		}
#endif
	}
}

İşte bu kadar!

yorum
  1. emrullo dedi ki:

    D:\untiy\antt\Temp\gradleOut\launcher\build\intermediates\merged_manıfests\release\AndroidManifest.xml:40: AAPT: error: unexpected element found in .

    Game scripts or other custom code contains OnMouse_ event handlers. Presence of such handlers might impact performance on handheld devices.

    • yasirkula dedi ki:

      Build’i bozan şey, ilk aldığınız hata. İkinci aldığınız şey bir uyarı, bu dersten veya şu dersten faydalanarak bu uyarıyı çözebilirsiniz ama build sorununuza etkisi olmaz. İlk hatadaki “unexpected element”i, < ve > sembolleri olmadan buraya yazmanız lazım.

  2. musti76 dedi ki:

    merhaba Yasir bey. Unity kullanarak güzel adalar oluşturdum. Sizden aldığım joystik desteği ile telefonda istediğim gibi gezinebiliyorum. Ancak sormak istediğim bir şeyler olacak. Şöyle ki; Unityde rock & boulds u indirdim. çok güzel kaya vb özellikler var. Aynı zamanda hazır bir terrainde konuşmuş içine. Unityde bunun tanıtım videosunu izlediğimde yerden bağımsız olarak hareket edildiğini ve manevra yapılarak her yapının altından geçildiğini gördüm. Bu işlemi nasıl yapabilirim acaba?

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.