Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

[RELEASED] Simple Multi-touch for Dumbs.

Discussion in 'Assets and Asset Store' started by yaapelsinko, May 22, 2014.

  1. yaapelsinko

    yaapelsinko

    Joined:
    Nov 16, 2013
    Posts:
    102
    Once I've faced the problem there is no convenient way to work with multitouch in Unity, I've created my own one, not to be as complex as those jet planes in the Asset Store, but to get an obvious way to work with multiple touches, treat them as close as possible to OnMouse events and never ever see Input.touches in my code.

    As UT refused to publish it on the asset store, I'll cut down other touch-related plugins' sales a bit with publishing my script here, mue-ge-ge. :twisted:
    Just copy the code into file.

    To add touch input implementation into your application just drag TouchListener script onto your main camera and add it as a script component. Ah, and don't forget that your objects must have a Collider or Collider2D component for being able to be hit by your input.

    Now you can use next methods in any of your scripts that are extensions of the MonoBehaviour class:

    OnTouchDown(Touch touch) - called when touch began on an Collider.
    OnTouchUp(Touch touch) - called when touch is ended.
    OnTouchUpAsButton(Touch touch) - called when the touch is ended on the same Collider as it was began.
    OnTouchEnter(Touch touch) - called when moving touch point entered an Collider.
    OnTouchExit(Touch touch) - called when moving touch point leaved an Collider.
    OnTouchOver(Touch touch) - called every frame touch point is over an Collider.
    OnTouchDrag(Touch touch) - called every frame when touch began on an Collider and is still continues.

    As you can see, it mimics OnMouse events. If, for example, you will touch two or more different objects simultaneously, each of them will receive corresponding messages from their 'own' touches. You also can access actual touch information through 'touch' parameter passed.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class TouchListener : MonoBehaviour
    6. {
    7.     public ColliderMode colliderMode = ColliderMode.Collider;
    8.     public enum ColliderMode
    9.     {
    10.         Collider,
    11.         Collider2D
    12.     }
    13.  
    14.     private Camera parentCamera;
    15.  
    16.     private List<TrackedObject> trackedObjectList = new List<TrackedObject>();
    17.     private class TrackedObject
    18.     {
    19.         public Touch touch;
    20.         public GameObject gameObject;
    21.  
    22.         public TrackedObject(Touch touch, GameObject gameObject)
    23.         {
    24.             this.touch = touch;
    25.             this.gameObject = gameObject;
    26.         }
    27.     }
    28.  
    29.     private List<TrackedTouch> trackedTouchList = new List<TrackedTouch>();
    30.     private class TrackedTouch
    31.     {
    32.         public int fingerId;
    33.         public Vector2 position;
    34.  
    35.         public TrackedTouch(int fingerId, Vector2 position)
    36.         {
    37.             this.fingerId = fingerId;
    38.             this.position = position;
    39.         }
    40.     }
    41.  
    42.     void Start()
    43.     {
    44.         this.parentCamera = this.GetComponent<Camera>();
    45.     }
    46.  
    47.     void Update()
    48.     {
    49.         if (enabled)
    50.         {
    51.             foreach (Touch touch in Input.touches)
    52.             {
    53.                 GameObject objectHit = null;
    54.  
    55.                 switch (colliderMode)
    56.                 {
    57.                     case ColliderMode.Collider:
    58.                         {
    59.                             Ray touchRay = this.parentCamera.ScreenPointToRay(touch.position);
    60.                             RaycastHit touchHit;
    61.                             bool isTouchHit = Physics.Raycast(touchRay, out touchHit, this.parentCamera.farClipPlane, this.parentCamera.cullingMask);
    62.                             objectHit = isTouchHit ? touchHit.collider.gameObject : null;
    63.                         }
    64.                         break;
    65.                     case ColliderMode.Collider2D:
    66.                         {
    67.                             Vector3 worldPoint = this.parentCamera.ScreenToWorldPoint(touch.position);
    68.                             Vector2 touchPosition = new Vector2(worldPoint.x, worldPoint.y);
    69.                             Collider2D collider = Physics2D.OverlapPoint(touchPosition, this.parentCamera.cullingMask,
    70.                                 this.transform.position.z + this.parentCamera.nearClipPlane,
    71.                                 this.transform.position.z + this.parentCamera.farClipPlane);
    72.                             objectHit = (collider != null) ? collider.gameObject : null;
    73.                         }
    74.                         break;
    75.                 }
    76.  
    77.                 switch (touch.phase)
    78.                 {
    79.                     case TouchPhase.Began:
    80.                         {
    81.                             if ((objectHit != null)  (!this.trackedObjectList.Exists(trObj => trObj.gameObject == objectHit)))
    82.                             {
    83.                                 this.trackedObjectList.Add(new TrackedObject(touch, objectHit));
    84.                                 objectHit.SendMessage("OnTouchDown", touch, SendMessageOptions.DontRequireReceiver);
    85.                             }
    86.                         }
    87.                         break;
    88.  
    89.                     case TouchPhase.Ended:
    90.                         {
    91.                             bool isTrackedObjectExists = this.trackedObjectList.Exists(trObj => trObj.touch.fingerId == touch.fingerId);
    92.                             GameObject trackedObject = isTrackedObjectExists ? this.trackedObjectList.Find(trObj => trObj.touch.fingerId == touch.fingerId).gameObject : null;
    93.  
    94.                             if (isTrackedObjectExists)
    95.                                 if (trackedObject == objectHit)
    96.                                 {
    97.                                     trackedObject.SendMessage("OnTouchUpAsButton", touch, SendMessageOptions.DontRequireReceiver);
    98.                                     trackedObject.SendMessage("OnTouchUp", touch, SendMessageOptions.DontRequireReceiver);
    99.                                 }
    100.                                 else
    101.                                     trackedObject.SendMessage("OnTouchUp", touch, SendMessageOptions.DontRequireReceiver);
    102.  
    103.                             this.trackedObjectList.RemoveAll(trObj => trObj.touch.fingerId == touch.fingerId);
    104.                         }
    105.                         break;
    106.  
    107.                     case TouchPhase.Moved:
    108.                         {
    109.                             Vector3 touchPointPrev = this.trackedTouchList.Exists(trTch => trTch.fingerId == touch.fingerId) ?
    110.                                 this.trackedTouchList.Find(trTch => trTch.fingerId == touch.fingerId).position : touch.position;
    111.                             Ray touchRayPrev = this.parentCamera.ScreenPointToRay(touchPointPrev);
    112.                             RaycastHit touchHitPrev;
    113.                             bool isTouchHitPrev = Physics.Raycast(touchRayPrev, out touchHitPrev, this.parentCamera.farClipPlane, this.parentCamera.cullingMask);
    114.                             GameObject objectHitPrev = isTouchHitPrev ? touchHitPrev.collider.gameObject : null;
    115.  
    116.                             bool isTrackedObjectExists = this.trackedObjectList.Exists(trObj => trObj.touch.fingerId == touch.fingerId);
    117.                             GameObject trackedObject = isTrackedObjectExists ? this.trackedObjectList.Find(trObj => trObj.touch.fingerId == touch.fingerId).gameObject : null;
    118.  
    119.                             if (isTrackedObjectExists)
    120.                             {
    121.                                 trackedObject.SendMessage("OnTouchDrag", touch, SendMessageOptions.DontRequireReceiver);
    122.                             }
    123.  
    124.                             if (objectHit == objectHitPrev)
    125.                             {
    126.                                 if (objectHit != null)
    127.                                     objectHit.SendMessage("OnTouchOver", touch, SendMessageOptions.DontRequireReceiver);
    128.                             }
    129.                             else
    130.                             {
    131.                                 if (objectHit != null)
    132.                                     objectHit.SendMessage("OnTouchEnter", touch, SendMessageOptions.DontRequireReceiver);
    133.  
    134.                                 if (objectHitPrev != null)
    135.                                     objectHitPrev.SendMessage("OnTouchExit", touch, SendMessageOptions.DontRequireReceiver);
    136.                             }
    137.  
    138.                         }
    139.                         break;
    140.  
    141.                     case TouchPhase.Stationary:
    142.                         {
    143.                             bool isTrackedObjectExists = this.trackedObjectList.Exists(trObj => trObj.touch.fingerId == touch.fingerId);
    144.                             GameObject trackedObject = isTrackedObjectExists ? this.trackedObjectList.Find(trObj => trObj.touch.fingerId == touch.fingerId).gameObject : null;
    145.  
    146.                             if (isTrackedObjectExists)
    147.                             {
    148.                                 trackedObject.SendMessage("OnTouchDrag", touch, SendMessageOptions.DontRequireReceiver);
    149.                             }
    150.  
    151.                             if (objectHit != null)
    152.                             {
    153.                                 objectHit.SendMessage("OnTouchOver", touch, SendMessageOptions.DontRequireReceiver);
    154.                             }
    155.                         }
    156.                         break;
    157.  
    158.                     case TouchPhase.Canceled:
    159.                         {
    160.                             this.trackedObjectList.RemoveAll(trObj => trObj.touch.fingerId == touch.fingerId);
    161.                         }
    162.                         break;
    163.                 }
    164.             }
    165.  
    166.             this.trackedTouchList.Clear();
    167.             foreach (Touch touch in Input.touches)
    168.                 this.trackedTouchList.Add(new TrackedTouch(touch.fingerId, touch.position));
    169.         }
    170.     }
    171. }
     
    Last edited: May 22, 2014
  2. ProjectOne

    ProjectOne

    Joined:
    Aug 9, 2010
    Posts:
    442
    Bookmarked, Thanks

    Will try it