从 Unity 播放器外部开始的触摸获取 touchInput
Getting touchInput from a touch that starts outside of the Unity player
我有一个嵌入到 React 应用程序中的 Unity WebGL 播放器。 React 应用程序具有拖放磁贴,可以将其拖放到 WebGL 播放器上。当瓷砖开始成为毒品时,统一开始光线投射,这样您就可以知道您将要掉落到屏幕中的哪个对象上。所有这些在使用鼠标时都能完美运行,但我注意到 Input.touchCount
总是 returns 0 除非触摸来自 WebGL 播放器内部。有谁知道解决这个问题?现在一直在抨击这个……
这是光线投射代码。就像我说的,它非常适合鼠标...但我无法返回 touch.position
。
public void LateUpdate()
{
if (SHOULD_CAST_RAY)
{
// always returning 0
Debug.Log(Input.touchCount);
RaycastHit hit;
Vector3 position = Input.touchSupported
&& Input.touchCount == 1
? new Vector3(Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, 0)
: Input.mousePosition;
if (Physics.Raycast(RigsCamera.ScreenPointToRay(position), out hit, CameraRigControllerScript.CameraDistanceMax * 1.5f, 1 << 10))
{
if (CURRENT_SELECTION == null)
{
CURRENT_SELECTION = UnsafeGetModelInstantiationFromRaycast(hit);
ApplySelectionIndication();
}
else if (!IsAlreadySelected(hit))
{
RemoveSelectionIndication();
CURRENT_SELECTION = UnsafeGetModelInstantiationFromRaycast(hit);
ApplySelectionIndication();
}
return;
}
if (CURRENT_SELECTION != null)
{
RemoveSelectionIndication();
CURRENT_SELECTION = null;
}
}
}
此外,如果我触摸 Unity WebGL 播放器上的屏幕,然后开始拖动我的 React 组件之一,它会向 Unity 发送消息以开始光线投射;我得到的 atouch.position 是在我触摸的点上,手指不动...见鬼?
如果您有 Unity 5+ 版本,您可以对所有内容使用 mousePosition,因为 Input class 对 Touch (0) 和 Mouse (0) 的处理完全相同,您尝试过吗?
Vector3 position = Input.touchSupported && Input.touchCount == 1
? new Vector3(Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, 0)
: Input.mousePosition;
尝试将其更改为仅
Vector3 position = Input.mousePosition;
我在 Unity forums 上发布了一个解决方案,以防将来此线程有任何更新。
在 WebGL 中,Unity Input
class 不会注册在 WebGL 播放器之外开始的触摸事件。为了解决这个问题,我使用了几个布尔值,这些值由我的 React 组件通过 GameInstance.SendMessage
方法切换;以及一个 Vector3 来存储从 React 发送的值,也是通过 SendMessage
。这是重要的 C# 位。如果有人有任何问题,请提出,我会引导您完成其余部分!
bool SHOULD_CAST_RAY;
bool USE_EXTERNAL_ORIGINATING_TOUCH_POS;
Vector3 EXTERNAL_ORIGINATING_TOUCH_POS;
public void LateUpdate()
{
if (SHOULD_CAST_RAY)
{
if (USE_EXTERNAL_ORIGINATING_TOUCH_POS && EXTERNAL_ORIGINATING_TOUCH_POS.z < 0) { return; }
RaycastHit hit;
Vector3 screenPoint = Input.mousePresent ? Input.mousePosition : Vector3.zero;
Vector3 viewportPoint = USE_EXTERNAL_ORIGINATING_TOUCH_POS ? RigsCamera.ScreenToViewportPoint(EXTERNAL_ORIGINATING_TOUCH_POS) : Vector3.zero;
if (Physics.Raycast(
USE_EXTERNAL_ORIGINATING_TOUCH_POS
? RigsCamera.ViewportPointToRay(new Vector3(viewportPoint.x, 1 - viewportPoint.y, 0))
: RigsCamera.ScreenPointToRay(screenPoint),
out hit,
CameraRigControllerScript.CameraDistanceMax * 1.5f,
1 << 10
)) {
if (CURRENT_SELECTION == null)
{
CURRENT_SELECTION = UnsafeGetModelInstantiationFromRaycast(hit);
ApplySelectionIndication();
}
else if (!IsAlreadySelected(hit))
{
RemoveSelectionIndication();
CURRENT_SELECTION = UnsafeGetModelInstantiationFromRaycast(hit);
ApplySelectionIndication();
}
return;
}
if (CURRENT_SELECTION != null)
{
RemoveSelectionIndication();
CURRENT_SELECTION = null;
}
}
}
// The below methods are used to control the raycasting from React through sendMessage
public void ClearExternalOriginatingTouchPosition()
{
EXTERNAL_ORIGINATING_TOUCH_POS = new Vector3(0, 0, -1f);
USE_EXTERNAL_ORIGINATING_TOUCH_POS = false;
}
public void DisableRaycasting()
{
SHOULD_CAST_RAY = false;
RemoveSelectionIndication();
CURRENT_SELECTION = null;
}
public void EnableRaycasting()
{
SHOULD_CAST_RAY = true;
}
public void SetExternalOriginatingTouchPosition(string csv)
{
string[] pos = csv.Split(',');
EXTERNAL_ORIGINATING_TOUCH_POS = new Vector3(float.Parse(pos[0]), float.Parse(pos[1]), 0);
USE_EXTERNAL_ORIGINATING_TOUCH_POS = true;
}
我有一个嵌入到 React 应用程序中的 Unity WebGL 播放器。 React 应用程序具有拖放磁贴,可以将其拖放到 WebGL 播放器上。当瓷砖开始成为毒品时,统一开始光线投射,这样您就可以知道您将要掉落到屏幕中的哪个对象上。所有这些在使用鼠标时都能完美运行,但我注意到 Input.touchCount
总是 returns 0 除非触摸来自 WebGL 播放器内部。有谁知道解决这个问题?现在一直在抨击这个……
这是光线投射代码。就像我说的,它非常适合鼠标...但我无法返回 touch.position
。
public void LateUpdate()
{
if (SHOULD_CAST_RAY)
{
// always returning 0
Debug.Log(Input.touchCount);
RaycastHit hit;
Vector3 position = Input.touchSupported
&& Input.touchCount == 1
? new Vector3(Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, 0)
: Input.mousePosition;
if (Physics.Raycast(RigsCamera.ScreenPointToRay(position), out hit, CameraRigControllerScript.CameraDistanceMax * 1.5f, 1 << 10))
{
if (CURRENT_SELECTION == null)
{
CURRENT_SELECTION = UnsafeGetModelInstantiationFromRaycast(hit);
ApplySelectionIndication();
}
else if (!IsAlreadySelected(hit))
{
RemoveSelectionIndication();
CURRENT_SELECTION = UnsafeGetModelInstantiationFromRaycast(hit);
ApplySelectionIndication();
}
return;
}
if (CURRENT_SELECTION != null)
{
RemoveSelectionIndication();
CURRENT_SELECTION = null;
}
}
}
此外,如果我触摸 Unity WebGL 播放器上的屏幕,然后开始拖动我的 React 组件之一,它会向 Unity 发送消息以开始光线投射;我得到的 atouch.position 是在我触摸的点上,手指不动...见鬼?
如果您有 Unity 5+ 版本,您可以对所有内容使用 mousePosition,因为 Input class 对 Touch (0) 和 Mouse (0) 的处理完全相同,您尝试过吗?
Vector3 position = Input.touchSupported && Input.touchCount == 1
? new Vector3(Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, 0)
: Input.mousePosition;
尝试将其更改为仅
Vector3 position = Input.mousePosition;
我在 Unity forums 上发布了一个解决方案,以防将来此线程有任何更新。
在 WebGL 中,Unity Input
class 不会注册在 WebGL 播放器之外开始的触摸事件。为了解决这个问题,我使用了几个布尔值,这些值由我的 React 组件通过 GameInstance.SendMessage
方法切换;以及一个 Vector3 来存储从 React 发送的值,也是通过 SendMessage
。这是重要的 C# 位。如果有人有任何问题,请提出,我会引导您完成其余部分!
bool SHOULD_CAST_RAY;
bool USE_EXTERNAL_ORIGINATING_TOUCH_POS;
Vector3 EXTERNAL_ORIGINATING_TOUCH_POS;
public void LateUpdate()
{
if (SHOULD_CAST_RAY)
{
if (USE_EXTERNAL_ORIGINATING_TOUCH_POS && EXTERNAL_ORIGINATING_TOUCH_POS.z < 0) { return; }
RaycastHit hit;
Vector3 screenPoint = Input.mousePresent ? Input.mousePosition : Vector3.zero;
Vector3 viewportPoint = USE_EXTERNAL_ORIGINATING_TOUCH_POS ? RigsCamera.ScreenToViewportPoint(EXTERNAL_ORIGINATING_TOUCH_POS) : Vector3.zero;
if (Physics.Raycast(
USE_EXTERNAL_ORIGINATING_TOUCH_POS
? RigsCamera.ViewportPointToRay(new Vector3(viewportPoint.x, 1 - viewportPoint.y, 0))
: RigsCamera.ScreenPointToRay(screenPoint),
out hit,
CameraRigControllerScript.CameraDistanceMax * 1.5f,
1 << 10
)) {
if (CURRENT_SELECTION == null)
{
CURRENT_SELECTION = UnsafeGetModelInstantiationFromRaycast(hit);
ApplySelectionIndication();
}
else if (!IsAlreadySelected(hit))
{
RemoveSelectionIndication();
CURRENT_SELECTION = UnsafeGetModelInstantiationFromRaycast(hit);
ApplySelectionIndication();
}
return;
}
if (CURRENT_SELECTION != null)
{
RemoveSelectionIndication();
CURRENT_SELECTION = null;
}
}
}
// The below methods are used to control the raycasting from React through sendMessage
public void ClearExternalOriginatingTouchPosition()
{
EXTERNAL_ORIGINATING_TOUCH_POS = new Vector3(0, 0, -1f);
USE_EXTERNAL_ORIGINATING_TOUCH_POS = false;
}
public void DisableRaycasting()
{
SHOULD_CAST_RAY = false;
RemoveSelectionIndication();
CURRENT_SELECTION = null;
}
public void EnableRaycasting()
{
SHOULD_CAST_RAY = true;
}
public void SetExternalOriginatingTouchPosition(string csv)
{
string[] pos = csv.Split(',');
EXTERNAL_ORIGINATING_TOUCH_POS = new Vector3(float.Parse(pos[0]), float.Parse(pos[1]), 0);
USE_EXTERNAL_ORIGINATING_TOUCH_POS = true;
}