Warning: Cannot modify header information - headers already sent by (output started at /var/www/lalieno.it/index.php:48) in /var/www/lalieno.it/inc/cookie.php on line 3
a cadenza discontinua
Come se fossi
BLOG

Unity 2D [E3] - Migliorare il touch nei device più piccoli

La creazione di un'interfaccia grafica è sempre stato compito arduo sopratutto se si vuole creare qualcosa che utilizzi diversi dispositivi con un infinità di risoluzioni,schermi etc...

Ho pensato che fosse utile implementare qualcosa per rendere il touch più efficiente soprattutto nei device più piccoli che è, senza ombra di dubbio, un alternativa alla creazione di un'interfaccia grafica dedicata. Una soluzione efficiente è la creazione di un collider che gestisca tutti i gli eventi che desideriamo, al fine di individuare l'oggetto più vicino compatibile con l'evento ed inviarglielo. Una sorta di manager touch.

Il collider occupa tutta la camera e è al di sopra di tutto, per praticità lo chiamo SmartTouchCollider. Questo intercetta tutti gli eventi, che vogliamo che gestisca e tramite il suo script individua l'oggetto più vicino.

Come cercare gli oggetti? 
Ci sono diversi modi per effettuare la ricerca:

  1. associare uno script client agli oggetti e ricercarli con GetComponentsInChildren:

    SmartTouchClientScript[] smartTouchClientsMainCameraCanvas = MainCameraCanvas.GetComponentsInChildren (); 

     
  2. Ricercare i collider

    MainCameraCanvas.GetComponentsInChildren ();


Detto ciò ecco un esempio di funzionamento:

Tramite lo SmartTouchScript associato allo SmartTouchCollider si cattura l'evento OnPointerDown ( per esempio ma è possibile gestirli tutti ), si ricerca l'oggetto (Object 1) più vicino e si invia l'evento a Object 1 tramite il SendMessage.

 

public void OnPointerDown (PointerEventData eventData)
{
	try {
		GameObject obj = getNearestSmartTouchClient (eventData.position, "OnPointerDown");
		if (obj != null) {
			obj.SendMessage ("OnPointerDown", eventData);
		}

	} catch (Exception e) {
		Debug.Log ("Ext" + e.ToString ());
	}
}

Questo in linea generale è l'idea base per gestire il touch, aggiungendo una tolleranza, cioè un valore che indica la distanza massima in cui cercare un oggetto, diventa davvero efficiente.

Nello SmartTouchScriptClient, nel caso abbiate scelto la ricerca tramite lo script, sarà sufficiente aggiunere gli eventi a cui l'oggetto debba rispondere.

Vi lo SmartTouchScript e Client d'esempio. Ovviamente per chiarimenti,consiglio,suggerimenti lasciate un commento.

using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;
using System.Collections.Generic;
using System;

public class SmartTouchScript : MonoBehaviour, IPointerClickHandler, IPointerUpHandler, IPointerDownHandler
{
	private GameObject MainCameraCanvas;
	private GameObject MainCamera;

	float tollerance = 2;

	void Awake ()
	{
		base.Init ();
		MainCameraCanvas = GameObject.Find ("MainCameraCanvas");

	}

	// Use this for initialization
	void Start ()
	{

	}

	public void OnPointerUp (PointerEventData eventData)
	{
		try {
			GameObject obj = getNearestSmartTouchClient (eventData.position, "OnPointerUp");
			if (obj != null) {
				obj.SendMessage ("OnPointerUp", eventData);
			}

		} catch (Exception e) {
			Debug.Log ("Ext" + e.ToString ());
		}
	}

	public void OnPointerDown (PointerEventData eventData)
	{
		try {
			GameObject obj = getNearestSmartTouchClient (eventData.position, "OnPointerDown");
			if (obj != null) {
				obj.SendMessage ("OnPointerDown", eventData);
			}

		} catch (Exception e) {
			Debug.Log ("Ext" + e.ToString ());
		}
	}

	
	public GameObject getNearestSmartTouchClient (Vector2 position, String eventToSearch)
	{
		GameObject nearestObject = null;
		float nearestDistance = 0.0f;

		//position to world point
		position = Camera.main.ScreenToWorldPoint (position);
			
		// search in canvas
		SmartTouchClientScript[] smartTouchClientsMainCameraCanvas = MainCameraCanvas.GetComponentsInChildren ();
		List smartTouchClients = new List (smartTouchClientsMainCameraCanvas);

		foreach (SmartTouchClientScript c in smartTouchClients) {
			
			// if events it's in list
			if (Array.IndexOf (c.responseEvents, eventToSearch) > -1) {
				Vector3 objectPosition = new Vector3 (c.gameObject.transform.position.x, c.gameObject.transform.position.y);
				float actualDistance = Vector2.Distance (position, new Vector2 (objectPosition.x, objectPosition.y));
				if (actualDistance < tollerance) {
					if (nearestObject == null) {
						nearestDistance = actualDistance;
						nearestObject = c.gameObject;
					} else {
						if (actualDistance < nearestDistance) {
							nearestDistance = actualDistance;
							nearestObject = c.gameObject;
						}
					}
				}
			}
		}
		return nearestObject;

	}

}
using UnityEngine;
using System.Collections;

public class SmartTouchClientScript : MonoBehaviour {

	public string[] responseEvents;

	// Use this for initialization
	void Start () {
	
	}	

}

di GuiZ
12/05/2016

Commenta

We'll never share your email with anyone else.