从 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;
}