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
相关产品推荐
相关产品推荐

