You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中UI检测PC正常运行但Android端失效问题求助

安卓Unity地图游戏菜单点击穿透问题(Unity Remote异常)

问题背景

开发安卓地图游戏时,点击带Collider的地图物体(国家)会弹出菜单。此前存在点击菜单时穿透触发关闭的问题,原因是逻辑设定为「点击其他带Collider的物体时关闭菜单」。通过射线检测特定UI层的脚本解决了PC端问题,但在Unity Remote中点击菜单仍会关闭,推测是UI检测不及时。

核心问题

PC端光标操作正常,但Unity Remote中点击菜单时菜单仍关闭,疑似UI元素检测延迟或失效。

相关代码

UI检测脚本(UIDETECTIONS)

public bool isOverUI;
private int UILayer;

private void Start()
{
    UILayer = LayerMask.NameToLayer("MAINMENUCOMPONENTS");
}

private void Update()
{
    print(IsPointerOverUIElement() ? "Over UI" : "Not over UI");
}

// 检测是否触摸/悬停在Unity UI元素上
public bool IsPointerOverUIElement()
{
    return IsPointerOverUIElement(GetEventSystemRaycastResults());
}

// 通过射线检测结果判断是否在UI上
private bool IsPointerOverUIElement(List<RaycastResult> eventSystemRaysastResults)
{
    for (int index = 0; index < eventSystemRaysastResults.Count; index++)
    {
        RaycastResult curRaysastResult = eventSystemRaysastResults[index];
        if (curRaysastResult.gameObject.layer == UILayer)
        {
            isOverUI = true;
            return true;
        }
    }
    isOverUI = false;
    return false;
}

// 获取当前鼠标/触摸位置的所有EventSystem射线检测结果
static List<RaycastResult> GetEventSystemRaycastResults()
{
    PointerEventData eventData = new PointerEventData(EventSystem.current);
    eventData.position = Input.mousePosition;
    List<RaycastResult> raysastResults = new List<RaycastResult>();
    EventSystem.current.RaycastAll(eventData, raysastResults);
    return raysastResults;
}

菜单逻辑代码

public UIDETECTIONS UID;

// 点击触发的逻辑片段
if (UID.isOverUI == true)
{
    // 点击UI时不做操作
}
else if (UID.isOverUI == false)
{
    if (infoMenuOn == false)
    {
        if (isCountryClicked == false)
        {
            isCountryClicked = true;
            infoMenuOn = true;
            Debug.Log("MENU ON");
        }
        else if (isCountryClicked == true)
        {
            isCountryClicked = false;
        }
    }
    else if (infoMenuOn == true && isCountryClicked == true)
    {
        infoMenuOn = false;
        isCountryClicked = false;
        Debug.Log("MENU OFF");
    }
}

解决方案

1. 修复触摸输入的位置映射问题

脚本仅使用Input.mousePosition,但Unity Remote模拟触摸时,鼠标坐标与实际触摸坐标可能存在延迟或映射偏差。修改GetEventSystemRaycastResults方法,优先处理触摸输入:

static List<RaycastResult> GetEventSystemRaycastResults()
{
    PointerEventData eventData = new PointerEventData(EventSystem.current);
    // 优先读取触摸坐标,适配移动端/Remote场景
    if (Input.touchCount > 0)
    {
        var touch = Input.GetTouch(0);
        // 仅在触摸开始时检测,避免重复触发
        if (touch.phase == TouchPhase.Began || touch.phase == TouchPhase.Stationary)
        {
            eventData.position = touch.position;
        }
    }
    else
    {
        eventData.position = Input.mousePosition;
    }
    List<RaycastResult> raysastResults = new List<RaycastResult>();
    EventSystem.current.RaycastAll(eventData, raysastResults);
    return raysastResults;
}

2. 实时检测替代帧延迟变量

当前isOverUI在Update中更新,菜单逻辑可能读取的是上一帧的旧值。直接在点击事件触发时调用检测方法,确保结果实时:

// 替换原有的菜单逻辑判断
if (UID.IsPointerOverUIElement())
{
    // 点击UI不执行任何操作
}
else
{
    if (infoMenuOn == false)
    {
        isCountryClicked = !isCountryClicked;
        if (isCountryClicked)
        {
            infoMenuOn = true;
            Debug.Log("MENU ON");
        }
    }
    else if (infoMenuOn && isCountryClicked)
    {
        infoMenuOn = false;
        isCountryClicked = false;
        Debug.Log("MENU OFF");
    }
}

3. 检查UI基础设置

  • 确认菜单所有元素都在MAINMENUCOMPONENTS层
  • 确保Canvas上存在GraphicRaycaster组件(UI射线检测必需)
  • 检查场景中的EventSystem未被禁用

4. 规避Unity Remote的延迟问题

Unity Remote本身存在输入延迟,建议直接部署到真机测试,或者关闭设备后台无关程序以减少性能占用。

内容的提问来源于stack exchange,提问作者Redierro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 11:15:36