The creation of a graphical interface has always been daunting task especially if you want to create something that uses different devices with an infinite number of resolutions, screens etc ...
I thought it was useful to implement something to make the most efficient touch especially in the smaller device which is, without a doubt, an alternative to creating an interface dedicated graphics. An efficient solution is the creation of a collider which manages all of the events that we wish, in order to locate thenearest object compatible with the event and send it. A sort of touch manager.
The collider takes up the whole room and is above all, for convenience I call SmartTouchCollider. This intercepts all events, we want to manage, and through his script locates the nearest object.
How to search for items?
There are several ways to search:
So here's an example of operation:
Through the SmartTouchScript associated with SmartTouchCollider you catch the OnPointerDown event (for example, but you can manage them all), you find the object (Object 1) closer, and you send the event to Object 1 through 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 ()); } }
This generally is the basic idea to handle the touch, adding a tolerance, that is, a value indicating the maximum distance in which to search for an object, it becomes really efficient.
In SmartTouchScriptClient, in case you have chosen the search through the script, simply aggiunere events to which the object is responsible.
There the SmartTouchScript and Client example. Obviously for clarification, advice, suggestions leave a comment.
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 () { } }