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

Unity C#问题:快速多次点击左键后按住,枪械射速过快

Unity 2D二战游戏射击系统问题解决:快速点击后射速异常加快

问题原因

快速多次点击左键时,每次Input.GetButtonDown("Fire1")都会启动一个新的DelayCoroutine协程,多个协程同时循环调用Shoot(),相当于多份开火逻辑同时执行,导致射速叠加变快。另外,StopCoroutine(DelayCoroutine())无法终止正在运行的协程——因为每次调用DelayCoroutine()都会生成新的协程实例,你终止的是刚创建的空实例,不是正在跑的那个。

解决方案1:用协程实例控制(保留协程写法)

通过保存当前运行的协程实例,确保同一时间只启动一个协程:

public float AutoFireDelay = 0.4f;
public bool isFiring = false;
// 存储当前正在运行的开火协程
private Coroutine fireCoroutine;

private void Update()
{
    if (Input.GetButtonDown("Fire1"))
    {
        isFiring = true;
        // 只有协程未运行时才启动
        if (fireCoroutine == null)
        {
            fireCoroutine = StartCoroutine(DelayCoroutine());
        }
    }

    if (Input.GetButtonUp("Fire1"))
    {
        isFiring = false;
        // 终止正在运行的协程并清空引用
        if (fireCoroutine != null)
        {
            StopCoroutine(fireCoroutine);
            fireCoroutine = null;
        }
    }
}

public IEnumerator DelayCoroutine()
{
    while (isFiring)
    {
        Shoot();
        yield return new WaitForSeconds(AutoFireDelay);
    }
    // 循环结束后清空协程引用,允许下次启动
    fireCoroutine = null;
}

解决方案2:时间戳写法(更简单,推荐新手使用)

放弃协程,用时间记录下一次允许开火的时间,完全避免多协程问题:

public float AutoFireDelay = 0.4f;
// 记录下一次可以开火的时间点
private float nextFireTime;

private void Update()
{
    // 直接判断是否按住开火键,且已到下次开火时间
    if (Input.GetButton("Fire1") && Time.time >= nextFireTime)
    {
        Shoot();
        // 更新下次开火时间
        nextFireTime = Time.time + AutoFireDelay;
    }
}

这个写法逻辑更直白,不管你点击多少次,只要没到nextFireTime就不会触发射击,完美解决射速异常问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 23:05:09