List
A question about detecting touch in Smart glasses
Posted Date: 2018-06-25 6:37     Edited Date: 2018-06-27 6:50     Writer: inactive

Please provide your development details as below;

1. SDK Version:3.5
2. Development Environment:Unity-Android
3. Tracker/Scanner:Tracker
4. License Type(Free / Pro-One Time Fee / Pro-Subscription / Enterprise):Tracker
5. Target Device(Optional):Epson Moverio BT-350

I am writing a image-tracking program with unity3d, and I writed a touch detected code in the update function of the ARCamera, such as below:

    

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

public class touchManager : MonoBehaviour {

    public LayerMask touchInputMast;
    private RaycastHit hit;
    // Use this for initialization
    void Start () {
        
    }
    
    // Update is called once per frame
    void Update () {
        if (Input.touchCount > 0)
        {
            foreach (Touch touch in Input.touches)
            {
                Camera[] camera = GetComponents<Camera>();
                Ray ray = camera[0].ScreenPointToRay(touch.position);
                if (Physics.Raycast(ray, out hit, Mathf.Infinity, touchInputMast.value))
                {
                    GameObject recipient = hit.transform.gameObject;
                    if (recipient.name == "Mona_Lisa_Eyes_Button")
                    {
                        if (touch.phase == TouchPhase.Began)
                        {
                            recipient.SendMessage("OnMouseDown");
                        }
                    }
                }
            }
        }
    }
}

 

    Beside, there is a OnMouseDown function in the script of the gameobject "Mona_Lisa_Eyes_Button", such as below:

 

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

public class Mona_Lisa_Eyes_Button : MonoBehaviour {

    public GameObject intro;
    //public LayerMask touchInputMast;
    //private RaycastHit hit;

    // Use this for initialization
    void Start () {
        
    }
    
    // Update is called once per frame
    void Update () {
        
    }

    private void OnMouseDown()
    {
        if (intro != null)
        {
            if (!intro.activeInHierarchy)
            {
                intro.SetActive(true);
            }
        }
    }
}

 

   But when I ran it in my smart glasses and touched that gameobject, nothing happend. I have no idea what the problem is.  Could anybody here help me find out the problem and teach me how to solve this problem? It will be a great favor for me. Thanks!

 

tedyage

Posted Date: 2018-06-25 8:28     Edited Date: 2018-06-25 8:28     Writer: inactive

Thanks for your interest in MAXST SDK.

When running in optical see-through mode, a new camera game object corresponding to both eyes (EyeLeft, EyeRight) is created under ARCamera. So, to use touch input, it must be through the currently displayed camera (EyeLeft / EyeRight).
Please refer to the following code for instructions.

void Update () {
 if (Input.touchCount > 0) {
  Camera EyeLeft = GetComponent<Camera>("EyeLeft");
  Ray ray = EyeLeft.ScreenPointToRay(Input.GetTouch(0).position);
  if (Physics.Raycast(ray, out hit, Mathf.Infinity, touchInputMast.value)) {
   GameObject recipient = hit.transform.gameObject;
   if (recipient.name == "Mona_Lisa_Eyes_Button") {
    ***
   }
  }  
 }
}

 

Thanks.

Sam

Maxst Support Team

Posted Date: 2018-06-25 9:55     Edited Date: 2018-06-25 9:55     Writer: inactive

As I know, the function GetComponent<>() has no parameter. And I tried your code in my function, It showed error line below the code.

 

How is that happened? 

Posted Date: 2018-06-26 5:04     Edited Date: 2018-06-26 5:04     Writer: inactive


Camera EyeLeft = GetComponentInChildren<Camera>("EyeLeft");

If you get an error in the above syntax, replace it with the following:

Camera EyeLeft = GameObject.Find("EyeLeft").GetComponent<Camera>();

 

Thanks.

Sam

Maxst Support Team

Posted Date: 2018-06-26 6:38     Edited Date: 2018-06-26 6:38     Writer: inactive

Hi Sam:

   I tried updating the camera as you have said before, but it still not working. I wrote the touchManager in both Unity_Editor mode (it gets mouseposition to send the touch event request.) and moverio glassses mode.  The Unity_Editor mode worked well, but the glasses mode is still not worked yet.

   The Gameobjects in the scene is like below:

                                                             

     And there isn't a gameobject named "EyeLeft" yet. Now I'm confused about it.

     The main code about touchManger is below:

 

   

public LayerMask touchInputMask;
    private RaycastHit hit;
    private List<GameObject> touchList = new List<GameObject>();
    private GameObject[] touchesOld;

    // Update is called once per frame
    void Update()
    {
#if !UNITY_EDITOR
        if (Input.GetMouseButton(0)||Input.GetMouseButtonDown(0)||Input.GetMouseButtonUp(0))
        {
            touchesOld = new GameObject[touchList.Count];
            touchList.CopyTo(touchesOld);
            touchList.Clear();


                Ray ray = GetComponent<Camera>().ScreenPointToRay(Input.mousePosition);

                if (Physics.Raycast(ray, out hit, touchInputMask))
                {
                    GameObject recipient = hit.transform.gameObject;
                    touchList.Add(recipient);
                    if (Input.GetMouseButtonDown(0))
                    {
                        recipient.SendMessage("OnTouchDown", hit.point, SendMessageOptions.DontRequireReceiver);
                    }

                    if (Input.GetMouseButtonUp(0))
                    {
                        recipient.SendMessage("OnTouchUp", hit.point, SendMessageOptions.DontRequireReceiver);
                    }
                    if (Input.GetMouseButton(0))
                    {
                        recipient.SendMessage("OnTouchStay", hit.point, SendMessageOptions.DontRequireReceiver);
                    }
                }

            foreach (GameObject g in touchesOld)
            {
                if (!touchList.Contains(g))
                {
                    g.SendMessage("OnTouchExit", hit.point, SendMessageOptions.DontRequireReceiver);
                }
            }
        }
#else
        if (Input.touchCount > 0)
        {
            touchesOld = new GameObject[touchList.Count];
            touchList.CopyTo(touchesOld);
            touchList.Clear();
            Camera EyeLeft = GameObject.Find("EyeLeft").GetComponent<Camera>();

            foreach (Touch touch in Input.touches)
            {
                Ray ray = EyeLeft.ScreenPointToRay(touch.position);

                if (Physics.Raycast(ray, out hit, touchInputMask))
                {
                    GameObject recipient = hit.transform.gameObject;
                    touchList.Add(recipient);
                    if (touch.phase == TouchPhase.Began)
                    {
                        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);
                }
            }
        }
#endif

    }

     

Posted Date: 2018-06-26 7:28     Edited Date: 2018-06-26 8:59     Writer: inactive

 

Please make sure that Collider is set on GameObject to be HitTest. Collider is a must for HitTest.

Test results are good.

Note that when you run the app in Optical See-Through mode, EyeLeft and EyeRight GameObject are dynamically created in the ARCamera sub node.

 

Thanks.

Sam

Maxst Support Team

Posted Date: 2018-06-26 8:24     Edited Date: 2018-06-26 8:24     Writer: inactive

I created a cube to be a button, and it got a box collider by default. The detail is below:

 

Do you mean I should remove this collider? I not so sure.

I tried it, but still nothing. Sorry mate.

 

Posted Date: 2018-06-27 0:49     Edited Date: 2018-06-27 0:49     Writer: inactive

Collider is a must for HitTest.

Try the following code. What messages are displayed? This code outputs the name of the collided GameObject.


Ray ray = EyeLeft.ScreenPointToRay(touch.position);
if (Physics.Raycast(ray, out hit, touchInputMask))
{
    GameObject recipient = hit.transform.gameObject;
    Debug.Log(recipient.name);
}


And in your code, "#if! UNITY_EDITOR" is wrong.
"#if UNITY_EDITOR" is correct.

 

Thanks.

Sam

Maxst Support Team

Posted Date: 2018-06-27 2:59     Edited Date: 2018-06-27 2:59     Writer: inactive

Hi Sam:

Here's the thing I forgot to tell you, that I was using the touch area on the controller to call the touch event.

I checked the logcat from the monitor of the android sdk tool, and I figured out that when I connected the glasses to my PC and touch the controller, the code within the if statement (Input.touchCount>0) didn't execute at all. MeanWhile, that piece of code ran well when I ran the program in my android phone.

So I am wondering, is there something wrong with my controller touch area? But it worked when I was running the other apps. 

So may be the class Input could not react or get the touch information of the controller, I don't know . Could you help me? 

Greate Appriciated! 

Posted Date: 2018-06-27 6:50     Edited Date: 2018-06-27 6:50     Writer: inactive

I check the Moverio tutorial video on youtube(https://www.youtube.com/watch?v=bVYhyc4gVA8&list=PLyXqcW1HsHRlY6rKQ3w3HvhJp0DEy3Flr&index=14) . It said when we using tracking pad to fire the touch method, the if statement should be Input.GetMouseButtonDown(0), rather than Input.touchCount>0. So I updated my code and try again, the code inside that if statement could execute.

but there was another problem. the if statement (Physics.Raycast(ray, out hit, Mathf.Infinity, touchInputMask)) was never true when I was using the tracking pad to point that cube. It always returned false. So the code within that if statement didn't execute. The code was below:

 

if (Physics.Raycast(ray, out hit, Mathf.Infinity, touchInputMask))
            {
                GameObject recipient = hit.transform.gameObject;
                Debug.Log("touch gameobject is " + recipient.name);
                if (Input.GetMouseButtonDown(0))
                {
                    recipient.SendMessage("OnTouchDown", hit.point, SendMessageOptions.DontRequireReceiver);
                }

                if (Input.GetMouseButtonUp(0))
                {
                    recipient.SendMessage("OnTouchUp", hit.point, SendMessageOptions.DontRequireReceiver);
                }
                if (Input.GetMouseButtonUp(0))
                {
                    recipient.SendMessage("OnTouchStay", hit.point, SendMessageOptions.DontRequireReceiver);
                }
            }
            else
            {
                Debug.Log("abc");
            }

 

I checked the logcat, and figured out it always output "abc" and never output "touch gameobject is xxx".