A question about detecting touch in Smart glasses
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
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
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?
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
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
}
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
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.
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
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!
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".