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

Unity 2D游戏碰撞检测阶段键盘空格输入偶尔失效问题求助

问题根源

你遇到的问题是Unity的输入检测和物理触发的生命周期不同步导致的:

  • Input.GetKeyDown的状态只会在渲染帧的Update调用周期内有效,每帧更新一次,按下的状态仅存续1个渲染帧
  • OnTriggerStay2D属于物理系统回调,按照物理帧率(默认50次/秒) 触发,和渲染帧的频率不完全对齐
    当你按下空格的渲染帧刚好没有对应的物理帧触发OnTriggerStay2D时,就会出现Update里检测到了按键,但碰撞体内的判定失效的问题,也就是你遇到的20%概率异常。

修复方案

把按键状态在Update里提前缓存,再到碰撞回调中读取,用完重置状态即可,修改后的代码如下:

public class Target: MonoBehaviour {

    public GameObject target; 
    // 新增缓存空格按下状态的变量
    private bool _isSpacePressed;

    void Update () {
        if (Input.GetKeyDown("space")) {
            Debug.Log("SPACE PRESSED!!");
            _isSpacePressed = true;
        }
    }

    private void OnTriggerEnter2D (Collider2D collision) {
        Debug.Log("Collision!");
    }

    private void OnTriggerStay2D(Collider2D other) {
        // 读缓存的按键状态
        if (_isSpacePressed) {
            Debug.Log("HIT!!");
            Score.score++;
        
            // 环形区域随机生成新目标代码,运行正常
            float distance = 2.034822f;
            float x = Random.Range(-2f, 2f);
            float y = Mathf.Pow(distance,2) - Mathf.Pow(x,2);
            y =  Mathf.Sqrt(y);
            float[] options = {y, -y};
            int randomIndex = Random.Range(0, 2); 
            y = options[randomIndex];
            Vector3 vector = new Vector3(x, y, 0);
            GameObject newTarget = Instantiate(target, vector, Quaternion.identity);
            Destroy(gameObject);
        }
    }

    private void LateUpdate() {
        // 每帧结束重置按键状态,避免状态残留
        _isSpacePressed = false;
    }
}

补充说明

如果后续你要适配移动端触摸输入,也可以用同样的缓存逻辑,把输入事件的状态提前存在变量里,再到物理回调中做判定,就能完全避免不同步导致的判定丢失问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 20:06:03