Tango/Unity - UI 不阻止屏幕上的触摸
Tango/Unity - UI not blocking touches on screen
我们正在构建一个类似于 "Kitten - Placing Virtual objects in AR" 的示例,如下所示:
https://developers.google.com/tango/apis/unity/unity-howto-placing-objects.
基本上当你触摸屏幕时,一只小猫会出现在现实世界的平面(地板)上。
在我们的应用程序中,我们有一个侧面菜单,带有几个按钮,每个按钮显示一个不同的游戏对象。我们想要检测屏幕上除 UI 以外的任何地方的触摸。我们希望 UI 在 Tango 中阻止触摸,并且只允许触摸在没有 UI 元素的屏幕区域上实例化相关游戏对象。
触摸特定代码在这里:
void Update() {
if (Input.touchCount == 1) {
// Trigger placepictureframe function when single touch ended.
Touch t = Input.GetTouch(0);
if (t.phase == TouchPhase.Ended) {
PlacePictureFrame(t.position);
}
}
}
(PlacePictureFrame()
在触摸位置放置一个相框对象。)
我找不到任何结合了触摸和 UI 的 Tango 示例。我尝试过一种名为 LeanTouch 的资产来阻止 UI 元素后面的触摸,但它似乎不适用于 Tango。请帮忙!
我试过使用方法 5:
虽然它确实将 PhysicsRaycaster
添加到 TangoARCamera
(标记为 MainCamera
),但无论您在哪里,OnPointerDown
方法都不会产生调试日志触摸屏幕。探戈是一个特例,所以这不是一个重复的问题。见下文:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PictureFrameUIController : MonoBehaviour, IPointerClickHandler {
public GameObject m_pictureFrame;
private TangoPointCloud m_pointCloud;
void Start() {
m_pointCloud = FindObjectOfType<TangoPointCloud>();
addPhysicsRaycaster();
}
void addPhysicsRaycaster() {
PhysicsRaycaster physicsRaycaster = GameObject.FindObjectOfType<PhysicsRaycaster>();
if (physicsRaycaster == null) {
Camera.main.gameObject.AddComponent<PhysicsRaycaster>();
}
}
public void OnPointerClick(PointerEventData eventData) {
Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name);
PlacePictureFrame(eventData.pointerCurrentRaycast.screenPosition);
}
//void Update() {
// if (Input.touchCount == 1) {
// // Trigger placepictureframe function when single touch ended.
// Touch t = Input.GetTouch(0);
// if (t.phase == TouchPhase.Ended) {
// PlacePictureFrame(t.position);
// }
// }
//}
void PlacePictureFrame(Vector2 touchPosition) {
// Find the plane.
Camera cam = Camera.main;
Vector3 planeCenter;
Plane plane;
if (!m_pointCloud.FindPlane(cam, touchPosition, out planeCenter, out plane)) {
Debug.Log("cannot find plane.");
return;
}
// Place picture frame on the surface, and make it always face the camera.
if (Vector3.Angle(plane.normal, Vector3.up) > 60.0f && Vector3.Angle(plane.normal, Vector3.up) < 140.0f) {
Vector3 forward = plane.normal;
// Vector3 right = Vector3.Cross(plane.normal, cam.transform.forward).normalized;
// Vector3 forward = Vector3.Cross(right, plane.normal).normalized;
Instantiate(m_pictureFrame, planeCenter, Quaternion.LookRotation(forward, Vector3.up));
} else {
Debug.Log("surface is not steep enough for picture frame to be placed on.");
}
}
public void DeleteAllFrames() {
GameObject[] frames = GameObject.FindGameObjectsWithTag("Frame");
if (frames == null) {
return;
}
foreach (GameObject frame in frames) {
Destroy(frame);
}
}
}
如果您想检测屏幕上除 UI control/component 之外的任何地方的点击,您必须检查指针是否位于 UI 上方 EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId)
.
如果在桌面上,请使用 EventSystem.current.IsPointerOverGameObject()
。您正在使用 Tango,所以 EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId)
。应该使用。
void Update()
{
if (Input.touchCount == 1)
{
//Trigger placepictureframe function when single touch ended.
Touch t = Input.GetTouch(0);
if (t.phase == TouchPhase.Ended)
{
//Make sure that pointer is not over UI before calling PlacePictureFrame
if (!EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
{
PlacePictureFrame(t.position);
}
}
}
}
编辑:
这似乎只适用于 TouchPhase.Began
。
更改 t.phase == TouchPhase.Ended
to t.phase == TouchPhase.Began
,这应该会按预期工作。请务必使用移动设备 device/tango 而不是鼠标进行测试。
我们正在构建一个类似于 "Kitten - Placing Virtual objects in AR" 的示例,如下所示:
https://developers.google.com/tango/apis/unity/unity-howto-placing-objects.
基本上当你触摸屏幕时,一只小猫会出现在现实世界的平面(地板)上。
在我们的应用程序中,我们有一个侧面菜单,带有几个按钮,每个按钮显示一个不同的游戏对象。我们想要检测屏幕上除 UI 以外的任何地方的触摸。我们希望 UI 在 Tango 中阻止触摸,并且只允许触摸在没有 UI 元素的屏幕区域上实例化相关游戏对象。
触摸特定代码在这里:
void Update() {
if (Input.touchCount == 1) {
// Trigger placepictureframe function when single touch ended.
Touch t = Input.GetTouch(0);
if (t.phase == TouchPhase.Ended) {
PlacePictureFrame(t.position);
}
}
}
(PlacePictureFrame()
在触摸位置放置一个相框对象。)
我找不到任何结合了触摸和 UI 的 Tango 示例。我尝试过一种名为 LeanTouch 的资产来阻止 UI 元素后面的触摸,但它似乎不适用于 Tango。请帮忙!
我试过使用方法 5:
虽然它确实将 PhysicsRaycaster
添加到 TangoARCamera
(标记为 MainCamera
),但无论您在哪里,OnPointerDown
方法都不会产生调试日志触摸屏幕。探戈是一个特例,所以这不是一个重复的问题。见下文:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PictureFrameUIController : MonoBehaviour, IPointerClickHandler {
public GameObject m_pictureFrame;
private TangoPointCloud m_pointCloud;
void Start() {
m_pointCloud = FindObjectOfType<TangoPointCloud>();
addPhysicsRaycaster();
}
void addPhysicsRaycaster() {
PhysicsRaycaster physicsRaycaster = GameObject.FindObjectOfType<PhysicsRaycaster>();
if (physicsRaycaster == null) {
Camera.main.gameObject.AddComponent<PhysicsRaycaster>();
}
}
public void OnPointerClick(PointerEventData eventData) {
Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name);
PlacePictureFrame(eventData.pointerCurrentRaycast.screenPosition);
}
//void Update() {
// if (Input.touchCount == 1) {
// // Trigger placepictureframe function when single touch ended.
// Touch t = Input.GetTouch(0);
// if (t.phase == TouchPhase.Ended) {
// PlacePictureFrame(t.position);
// }
// }
//}
void PlacePictureFrame(Vector2 touchPosition) {
// Find the plane.
Camera cam = Camera.main;
Vector3 planeCenter;
Plane plane;
if (!m_pointCloud.FindPlane(cam, touchPosition, out planeCenter, out plane)) {
Debug.Log("cannot find plane.");
return;
}
// Place picture frame on the surface, and make it always face the camera.
if (Vector3.Angle(plane.normal, Vector3.up) > 60.0f && Vector3.Angle(plane.normal, Vector3.up) < 140.0f) {
Vector3 forward = plane.normal;
// Vector3 right = Vector3.Cross(plane.normal, cam.transform.forward).normalized;
// Vector3 forward = Vector3.Cross(right, plane.normal).normalized;
Instantiate(m_pictureFrame, planeCenter, Quaternion.LookRotation(forward, Vector3.up));
} else {
Debug.Log("surface is not steep enough for picture frame to be placed on.");
}
}
public void DeleteAllFrames() {
GameObject[] frames = GameObject.FindGameObjectsWithTag("Frame");
if (frames == null) {
return;
}
foreach (GameObject frame in frames) {
Destroy(frame);
}
}
}
如果您想检测屏幕上除 UI control/component 之外的任何地方的点击,您必须检查指针是否位于 UI 上方 EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId)
.
如果在桌面上,请使用 EventSystem.current.IsPointerOverGameObject()
。您正在使用 Tango,所以 EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId)
。应该使用。
void Update()
{
if (Input.touchCount == 1)
{
//Trigger placepictureframe function when single touch ended.
Touch t = Input.GetTouch(0);
if (t.phase == TouchPhase.Ended)
{
//Make sure that pointer is not over UI before calling PlacePictureFrame
if (!EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
{
PlacePictureFrame(t.position);
}
}
}
}
编辑:
这似乎只适用于 TouchPhase.Began
。
更改 t.phase == TouchPhase.Ended
to t.phase == TouchPhase.Began
,这应该会按预期工作。请务必使用移动设备 device/tango 而不是鼠标进行测试。