Log in or register to post comments

Augmented Reality - Make GameObject touchable

November 27, 2015 - 8:26pm #1

I am developing an iPad-based augmented reality app.  I am struggling with how to make my GameObjects touchable.  I've looked all around forums and some YouTube tutorials but nothing seems to work out.  

This is my hierarchy (also attached as screenshot below).

ARCamera
--Camera

ImageTarget
--Cube

ImageTarget
--Cube

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

touchableManager code:

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

public class touchableManager : MonoBehaviour
{
    public LayerMask touchInputMask;
    private List<GameObjecttouchList = new List<GameObject>();
    private GameObject[] touchesOld;
    private RaycastHit hit;

    void Update () 
    {
        if (Input.touchCount > 0)
        {
            touchesOld = new GameObject[touchList.Count];
            touchList.CopyTo(touchesOld);
            touchList.Clear();

            foreach (Touch touch in Input.touches)
            {
                Ray ray = GetComponent<Camera>().ScreenPointToRay (touch.position);    //attached the main camera

                if (Physics.Raycast(rayout hit100ftouchInputMask.value))
                {

                    GameObject recipient = hit.transform.gameObject;
                    touchList.Add(recipient);

                    if (touch.phase == TouchPhase.Began) {
                        recipient.SendMessage ("onTouchDown"hit.pointSendMessageOptions.DontRequireReceiver);
                    }

                    if (touch.phase == TouchPhase.Ended) {
                        recipient.SendMessage ("onTouchUp"hit.pointSendMessageOptions.DontRequireReceiver);
                    }

                    if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved) {
                        recipient.SendMessage ("onTouchStay"hit.pointSendMessageOptions.DontRequireReceiver);
                    }

                    if (touch.phase == TouchPhase.Canceled) {
                        recipient.SendMessage ("onTouchExit"hit.pointSendMessageOptions.DontRequireReceiver);
                    }
                }
            }
            foreach (GameObject g in touchesOld)
            {
                if (!touchList.Contains(g)) 
                {
                    g.SendMessage("onTouchExit"hit.pointSendMessageOptions.DontRequireReceiver);
                }
            }
        }
    }
}

 

touchableGameObject code

using UnityEngine;
using UnityEngine;
using System.Collections;

public class touchableGameobject : MonoBehaviour
{
    public Color defaultColor;
    public Color selectedColor;
    private Material mat;
    
    void Start()
    {
        mat = GetComponent<Renderer>().material;
    }
    
    void onTouchDown()
    {
        mat.color = selectedColor;
    }
    
    void onTouchUp()
    {
        mat.color = defaultColor;
    }
    
    void onTouchStay()
    {
        mat.color = selectedColor;
    }
    
    void onTouchExit()
    {
        mat.color = defaultColor;
    }
}

 

I've attached a screenshot of my hierarchy along with the result so far.  I am able to get my two GameObjects to appear over the AR markers.  However, I am unable to touch them and trigger my color changes.  Nothing happens.  Please, any help is greatly appreciated.

AttachmentSize
Image icon screen1.png170.19 KB
Image icon IMG_0056.PNG1.5 MB

Augmented Reality - Make GameObject touchable

December 9, 2015 - 6:46pm #3
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.cs to a Game Object and attach touchableManager.cs to the ARCamera.
 
touchableManager.cs:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class touchableManager : MonoBehaviour
{
	public LayerMask touchInputMask;
	private List<GameObject> touchList = new List<GameObject>();
	private GameObject[] touchesOld;
	private RaycastHit hit;

	void Update () 
	{
		if (Input.touchCount > 0)
		{
			touchesOld = new GameObject[touchList.Count];
			touchList.CopyTo(touchesOld);
			touchList.Clear();

			foreach (Touch touch in Input.touches)
			{
				Ray ray = Camera.main.ScreenPointToRay(touch.position);    //attached the main camera

				if (Physics.Raycast(ray, out hit, Mathf.Infinity, touchInputMask.value))
				{
					GameObject recipient = hit.transform.gameObject;
					touchList.Add(recipient);

					if (touch.phase == TouchPhase.Began) {
						Debug.Log("Touched: " + recipient.name);
						recipient.SendMessage ("onTouchDown", hit.point, SendMessageOptions.DontRequireReceiver);
					}

					if (touch.phase == TouchPhase.Ended) {
						recipient.SendMessage ("onTouchUp", hit.point, SendMessageOptions.DontRequireReceiver);
					}

					if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved) {
						recipient.SendMessage ("onTouchStay", hit.point, SendMessageOptions.DontRequireReceiver);
					}

					if (touch.phase == TouchPhase.Canceled) {
						recipient.SendMessage ("onTouchExit", hit.point, SendMessageOptions.DontRequireReceiver);
					}
				}
			}
			foreach (GameObject g in touchesOld)
			{
				if (!touchList.Contains(g)) 
				{
					g.SendMessage("onTouchExit", hit.point, SendMessageOptions.DontRequireReceiver);
				}
			}
		}
	}
}

 

touchableGameObject.cs


using UnityEngine;
using System.Collections;

public class touchableGameobject : MonoBehaviour
{
	public Color defaultColor;
	public Color selectedColor;
	private Material mat;
	
	void Start()
	{
		mat = GetComponent<Renderer>().material;
	}
	
	void onTouchDown()
	{
		mat.color = selectedColor;
	}
	
	void onTouchUp()
	{
		mat.color = defaultColor;
	}
	
	void onTouchStay()
	{
		mat.color = selectedColor;
	}
	
	void onTouchExit()
	{
		mat.color = defaultColor;
	}
}
 
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.

Augmented Reality - Make GameObject touchable

December 7, 2015 - 5:44pm #2
Log in or register to post comments