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

Unity FPS相机按ESC切换后光标无法重新锁定隐藏问题

问题根源
  • 现有代码仅在切换回锁定状态时设置了Cursor.visible属性,解锁分支未显式指定光标可见性,完全依赖Unity引擎的自动切换行为,极易出现引擎层状态和业务逻辑不同步的问题。
  • 直接读取Cursor.lockState的实时返回值做切换判断可靠性差:游戏窗口失焦、系统弹窗弹出、编辑器环境操作都可能在底层修改光标锁定状态,导致分支判断失准、属性设置不生效。
  • 未做光标状态的显式初始化,也没有处理窗口焦点恢复后的状态重置,逻辑容易被系统默认行为干扰。
修复方案
  1. 维护独立的布尔变量记录业务层预期的光标锁定状态,不直接依赖引擎返回的实时光标状态做逻辑判断
  2. 每次切换状态时同时显式设置Cursor.lockState和Cursor.visible两个属性,锁定/解锁两个状态的属性都要明确赋值,不依赖引擎的自动补全逻辑
  3. 游戏启动初始化、窗口重新获得焦点时,主动按照业务层记录的状态重设光标属性,覆盖系统的默认修改

修复后的完整代码如下:

// 业务层维护的光标锁定标记,初始状态为锁定
private bool isCursorLocked = true;

void Start()
{
    // 启动时显式初始化光标状态,不依赖引擎默认值
    UpdateCursorState();
}

void Update()
{
    HandleCursorToggle();
    if (isCursorLocked)
    {
        LookAround();
    }
}

void HandleCursorToggle()
{
    if (Input.GetKeyDown(KeyCode.Escape))
    {
        // 直接翻转业务层状态标记
        isCursorLocked = !isCursorLocked;
        UpdateCursorState();
    }
}

// 抽离统一的光标状态设置方法,避免漏写属性
void UpdateCursorState()
{
    Cursor.lockState = isCursorLocked ? CursorLockMode.Locked : CursorLockMode.None;
    Cursor.visible = !isCursorLocked;
}

// 窗口重新获得焦点时强制重设光标,解决失焦导致的状态异常
private void OnApplicationFocus(bool hasFocus)
{
    if (hasFocus)
    {
        UpdateCursorState();
    }
}
补充说明
  • Unity编辑器环境下运行时,偶尔会因为编辑器自身的光标逻辑出现状态延迟,打包后运行逻辑会完全稳定。
  • 如果需要解锁时光标不超出游戏窗口范围,可以将解锁状态对应的CursorLockMode.None替换为CursorLockMode.Confined,按需调整即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:57:17