Search Unity

Make GameObjects Touchable in Unity - Augmented Reality

Discussion in 'Scripting' started by noblerare, Nov 28, 2015.

  1. noblerare

    noblerare

    Joined:
    Nov 11, 2015
    Posts:
    11
    I am trying to develop an augmented reality iOS app in Unity with Vuforia SDK. I am struggling with trying to make my GameObjects touchable.

    Currently, I am able to get my GameObjects to hover over my markers as expected. However, when tapping on them, nothing happens.

    Here is my hierarchy. I've attached pictures below.

    ARCamera
    --Camera

    ImageTarget
    --Cube

    ImageTarget
    --Cube

    Now, I've been browsing forums and online tutorials for how to do this and here is the code I have so far.

    I have two C# scripts: touchableManager (attached to ARCamera) and touchableGameobject (attached to Cube and Cube)

    touchableManager:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class touchableManager : MonoBehaviour
    7. {
    8.     public LayerMask touchInputMask;
    9.     private List<GameObject> touchList = new List<GameObject>();
    10.     private GameObject[] touchesOld;
    11.     private RaycastHit hit;
    12.  
    13.     void Update ()
    14.     {
    15.         Debug.Log ("Hello");
    16.         if (Input.touchCount > 0)
    17.         {
    18.             touchesOld = new GameObject[touchList.Count];
    19.             touchList.CopyTo(touchesOld);
    20.             touchList.Clear();
    21.  
    22.             Debug.Log ("Hello2");
    23.  
    24.             foreach (Touch touch in Input.touches)
    25.             {
    26.                 Ray ray = GetComponent<Camera>().ScreenPointToRay (touch.position);    //attached the main camera
    27.  
    28.                 if (Physics.Raycast(ray, out hit, 100f, touchInputMask.value))
    29.                 {
    30.                     Debug.Log ("Hello3");
    31.  
    32.                     GameObject recipient = hit.transform.gameObject;
    33.                     touchList.Add(recipient);
    34.  
    35.                     if (touch.phase == TouchPhase.Began) {
    36.                         recipient.SendMessage ("onTouchDown", hit.point, SendMessageOptions.DontRequireReceiver);
    37.                     }
    38.  
    39.                     if (touch.phase == TouchPhase.Ended) {
    40.                         recipient.SendMessage ("onTouchUp", hit.point, SendMessageOptions.DontRequireReceiver);
    41.                     }
    42.  
    43.                     if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved) {
    44.                         recipient.SendMessage ("onTouchStay", hit.point, SendMessageOptions.DontRequireReceiver);
    45.                     }
    46.  
    47.                     if (touch.phase == TouchPhase.Canceled) {
    48.                         recipient.SendMessage ("onTouchExit", hit.point, SendMessageOptions.DontRequireReceiver);
    49.                     }
    50.                 }
    51.             }
    52.             foreach (GameObject g in touchesOld)
    53.             {
    54.                 if (!touchList.Contains(g))
    55.                 {
    56.                     g.SendMessage("onTouchExit", hit.point, SendMessageOptions.DontRequireReceiver);
    57.                 }
    58.             }
    59.         }
    60.     }
    61. }
    62.  
    touchableGameobject:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class touchableGameobject : MonoBehaviour
    6. {
    7.     public Color defaultColor;
    8.     public Color selectedColor;
    9.     private Material mat;
    10.    
    11.     void Start()
    12.     {
    13.         mat = GetComponent<Renderer>().material;
    14.     }
    15.    
    16.     void onTouchDown()
    17.     {
    18.         mat.color = selectedColor;
    19.     }
    20.    
    21.     void onTouchUp()
    22.     {
    23.         mat.color = defaultColor;
    24.     }
    25.    
    26.     void onTouchStay()
    27.     {
    28.         mat.color = selectedColor;
    29.     }
    30.    
    31.     void onTouchExit()
    32.     {
    33.         mat.color = defaultColor;
    34.     }
    35. }
    36.  
    So far, all my application does is reveal the two GameObjects. When I tap them, nothing happens. The code should change the color of the cubes when tapped.

    I've attached two screenshots below.

    Please, any help would be greatly appreciated. Please guide me along the right path.
     

    Attached Files:

  2. noblerare

    noblerare

    Joined:
    Nov 11, 2015
    Posts:
    11
    I'll answer my own question in the hopes that anybody who comes after me may find this helpful.

    The following bits of code worked for me. Attach touchableGameObject to a Game Object and attach touchableManager to the ARCamera.

    touchableGameObject.cs:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class touchableGameobject : MonoBehaviour
    6. {
    7.     public Color defaultColor;
    8.     public Color selectedColor;
    9.     private Material mat;
    10.  
    11.     void Start()
    12.     {
    13.         mat = GetComponent<Renderer>().material;
    14.     }
    15.  
    16.     void onTouchDown()
    17.     {
    18.         mat.color = selectedColor;
    19.     }
    20.  
    21.     void onTouchUp()
    22.     {
    23.         mat.color = defaultColor;
    24.     }
    25.  
    26.     void onTouchStay()
    27.     {
    28.         mat.color = selectedColor;
    29.     }
    30.  
    31.     void onTouchExit()
    32.     {
    33.         mat.color = defaultColor;
    34.     }
    35. }
    36.  
    touchableManager.cs

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class touchableManager : MonoBehaviour
    7. {
    8.     public LayerMask touchInputMask;
    9.     private List<GameObject> touchList = new List<GameObject>();
    10.     private GameObject[] touchesOld;
    11.     private RaycastHit hit;
    12.  
    13.     void Update ()
    14.     {
    15.         if (Input.touchCount > 0)
    16.         {
    17.             touchesOld = new GameObject[touchList.Count];
    18.             touchList.CopyTo(touchesOld);
    19.             touchList.Clear();
    20.  
    21.             foreach (Touch touch in Input.touches)
    22.             {
    23.                 Ray ray = Camera.main.ScreenPointToRay(touch.position);    //attached the main camera
    24.  
    25.                 if (Physics.Raycast(ray, out hit, Mathf.Infinity, touchInputMask.value))
    26.                 {
    27.                     GameObject recipient = hit.transform.gameObject;
    28.                     touchList.Add(recipient);
    29.  
    30.                     if (touch.phase == TouchPhase.Began) {
    31.                         Debug.Log("Touched: " + recipient.name);
    32.                         recipient.SendMessage ("onTouchDown", hit.point, SendMessageOptions.DontRequireReceiver);
    33.                     }
    34.  
    35.                     if (touch.phase == TouchPhase.Ended) {
    36.                         recipient.SendMessage ("onTouchUp", hit.point, SendMessageOptions.DontRequireReceiver);
    37.                     }
    38.  
    39.                     if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved) {
    40.                         recipient.SendMessage ("onTouchStay", hit.point, SendMessageOptions.DontRequireReceiver);
    41.                     }
    42.  
    43.                     if (touch.phase == TouchPhase.Canceled) {
    44.                         recipient.SendMessage ("onTouchExit", hit.point, SendMessageOptions.DontRequireReceiver);
    45.                     }
    46.                 }
    47.             }
    48.             foreach (GameObject g in touchesOld)
    49.             {
    50.                 if (!touchList.Contains(g))
    51.                 {
    52.                     g.SendMessage("onTouchExit", hit.point, SendMessageOptions.DontRequireReceiver);
    53.                 }
    54.             }
    55.         }
    56.     }
    57. }
    58.  
    In addition, in the Unity editor, on the top right, click the "Layers" dropdown. Edit Layer. I just typed "Touch Input" into a field (e.g. User Layer 8, or whatever is available). Then, select the ARCamera and in the Inspector tab, select your newly-named layer in the "Layer" dropdown. Do the same for each GameObject. Also, in ARCamera, under the "touchableManager" component, you also have to select your newly-named layer in the "Touch Input Mask" dropdown.

    Hope this helps someone.