Unity FPS射击脚本输入持续触发问题求助
问题根源与解决方案
核心问题:输入检测不该放在FixedUpdate里
FixedUpdate是按固定时间间隔执行(默认0.02秒一次),而Input.GetKey/Input.GetButton这类API在按住按键时会持续返回true,导致FixedUpdate每执行一次就触发一次对应逻辑,出现重复调用Reload、射击异常的情况。
具体修复步骤:
- 输入检测全移到Update方法:Update按帧率执行,专门处理玩家输入更合理,FixedUpdate只保留物理相关逻辑
- 替换
Input.GetKey(KeyCode.R)为Input.GetKeyDown(KeyCode.R):GetKeyDown只在按键按下的第一帧返回true,避免按住R时重复触发Reload协程 - 射击逻辑的触发控制:把Fire1的输入检测移到Update,射击执行可留在FixedUpdate(如需物理同步),或直接在Update里执行,保留原射速控制逻辑
修改后的代码示例:
// 新增标记变量,用于传递射击指令 private bool isNeedShoot = false; void Update() { if(isReloading) return; // 换弹输入:仅按键按下瞬间触发 if(Input.GetKeyDown(KeyCode.R)) { Debug.Log("R key was pressed."); StartCoroutine(Reload()); return; } // 弹药耗尽自动换弹 if (currentAmmo <= 0) { StartCoroutine(Reload()); return; } // 射击输入检测,满足射速条件后标记需要射击 if(Input.GetButton("Fire1") && Time.time >= nextTimeToFire) { nextTimeToFire = Time.time + 1f / fireRate; isNeedShoot = true; } } void FixedUpdate() { if(isReloading || !isNeedShoot) return; Shooting(); isNeedShoot = false; } IEnumerator Reload() { isReloading = true; UIController.instance.reloadMSG.gameObject.SetActive(true); Debug.Log("reloading"); yield return new WaitForSeconds(reloadTime); currentAmmo = maxAmmo; isReloading = false; UIController.instance.reloadMSG.gameObject.SetActive(false); } private void Shooting() { currentAmmo--; Debug.Log("Current Ammo:" + currentAmmo); RaycastHit hit; if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range)) { GameObject bulletImpactObject = Instantiate(bulletImpact, hit.point + (hit.normal * 0.002f), Quaternion.LookRotation(hit.normal, Vector3.up)); Destroy(bulletImpactObject, 10f); } UIController.instance.ammoTXT.text = $"{currentAmmo} / {maxAmmo}"; }
额外说明:
如果射击逻辑不需要严格和物理帧同步,也可以直接把Shooting放在Update的输入判断里,去掉isNeedShoot标记,实现更简洁。
内容的提问来源于stack exchange,提问作者totames
相关产品推荐
相关产品推荐

