如何在光标锁定状态下点击World Space Canvas按钮?
问题描述

我有一个挂载了按钮(Button4)的World Space Canvas,光标锁定状态下无法点击该按钮,只有解锁光标时才能点击,这不是理想方案,怀疑是光标设置的问题。
尝试过从屏幕中心发射射线检测,但需要碰撞体:
- 添加2D碰撞体时,因为文本和按钮画布会随移动跟随,导致2D碰撞体混乱;
- 添加3D碰撞体时,检测到的点击对象是父对象(Edwin模型),无法识别实际点击的按钮。
希望能实现在光标锁定状态下直接点击按钮,求解决思路。
解决思路
1. 优化射线检测的层级与碰撞体
- 给按钮所在的World Space Canvas设置专属层级,射线检测时仅针对该层级,避免误触父对象的3D碰撞体。
- 给按钮的Image组件添加适配大小的Box Collider(3D碰撞体),同时调整父对象的碰撞体范围,确保不覆盖按钮区域;或者在Physics设置中让父对象的碰撞层与按钮层级相互忽略。
2. 自定义锁定光标下的点击触发逻辑
- 在光标锁定状态下,通过
Input.GetMouseButtonDown(0)捕捉点击,从屏幕中心发射射线检测按钮:void Update() { if (Cursor.lockState == CursorLockMode.Locked && Input.GetMouseButtonDown(0)) { Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2f, Screen.height / 2f, 0f)); if (Physics.Raycast(ray, out RaycastHit hit)) { Button targetBtn = hit.collider.GetComponentInParent<Button>(); if (targetBtn != null && targetBtn.gameObject.name == "Button4") { targetBtn.onClick.Invoke(); } } } } - 给按钮添加专属标签(比如
UI_Button),可以更高效地判断点击对象。
3. 基于EventSystem适配锁定光标
- 自定义
StandaloneInputModule,重写光标位置获取逻辑,让EventSystem在光标锁定时识别屏幕中心为光标位置:public class LockedCursorInputModule : StandaloneInputModule { public override Vector2 GetMousePosition() { return Cursor.lockState == CursorLockMode.Locked ? new Vector2(Screen.width / 2f, Screen.height / 2f) : base.GetMousePosition(); } } - 替换原EventSystem中的
StandaloneInputModule为这个自定义模块,此时World Space Canvas的Graphic Raycaster会自动处理射线检测,无需额外添加碰撞体,按钮可直接响应点击。
4. 排查光标设置细节
- 确认光标锁定时
Cursor.visible = false,但不要禁用UI的Graphic Raycaster组件; - 检查是否有其他脚本在光标锁定时修改了EventSystem的启用状态,如有则调整逻辑保持EventSystem正常运行。
内容的提问来源于stack exchange,提问作者Matthew Z
相关产品推荐
相关产品推荐

