Unity旧输入系统下同帧多方向同时射击功能失效问题
问题原因
和Unity旧输入系统的多按键检测能力无关,故障来自两个逻辑错误:
- 射速冷却逻辑是全局单次触发的:你在
SpawnBullet方法里写了冷却判断,只要任意一个方向的射击方法调用了SpawnBullet并通过判断,就会立刻把currentTime重置为0,同帧后续其他方向的射击调用进入SpawnBullet时,都会因为currentTime < currentFireRate直接return,不会生成子弹。比如同时按上+右键时,第一个触发的ShootUp()成功生成子弹、重置计时器,紧接着执行的ShootRight()就会被冷却拦截。 - 输入判断逻辑冗余:单独判断四个单方向按键后又额外写了右上组合键的判断,会导致单按方向键时重复调用对应射击方法,平白触发无意义的冷却校验。
修复方法
把冷却判断从单颗子弹生成逻辑中抽离,先统一校验冷却状态,冷却就绪后再一次性读取所有按下的方向键、批量生成子弹,最后统一重置冷却计时器即可。
- 拆分原
SpawnBullet方法,移除内部的冷却判断,只保留子弹生成逻辑:
public void SpawnBullet(Vector3 direction, Quaternion rotation) { Bullet instanceOfBullet = Instantiate(BulletPrefab); instanceOfBullet.transform.position = transform.position; instanceOfBullet.direction = direction; instanceOfBullet.transform.rotation = rotation; instanceOfBullet.tag = "Player Bullet"; }
- 重写Update中的输入和冷却逻辑,删除冗余的组合键判断:
void Update() { currentTime += Time.deltaTime; // 冷却未就绪直接跳过所有射击逻辑 if (currentTime < currentFireRate) return; bool isFired = false; // 独立检测四个方向,多键同时按下时会进入多个分支,自动实现多方向射击 if (Input.GetKey(KeyCode.UpArrow)) { SpawnBullet(Vector3.up, Quaternion.Euler(0,0,0)); isFired = true; } if (Input.GetKey(KeyCode.DownArrow)) { SpawnBullet(Vector3.down, Quaternion.Euler(0,0,180)); isFired = true; } if (Input.GetKey(KeyCode.LeftArrow)) { SpawnBullet(Vector3.left, Quaternion.Euler(0,0,90)); isFired = true; } if (Input.GetKey(KeyCode.RightArrow)) { SpawnBullet(Vector3.right, Quaternion.Euler(0,0,-90)); isFired = true; } // 只要本帧有任意方向生成子弹,统一重置冷却 if (isFired) currentTime = 0; }
可选扩展:斜向单子弹射击
如果你的设计需求是多键同按时发射斜向子弹、而非多个垂直方向的子弹,可以把输入检测改成方向向量累加的方式,避免多子弹生成:
void Update() { currentTime += Time.deltaTime; if (currentTime < currentFireRate) return; Vector2 shootDir = Vector2.zero; if (Input.GetKey(KeyCode.UpArrow)) shootDir.y += 1; if (Input.GetKey(KeyCode.DownArrow)) shootDir.y -= 1; if (Input.GetKey(KeyCode.LeftArrow)) shootDir.x -= 1; if (Input.GetKey(KeyCode.RightArrow)) shootDir.x += 1; if (shootDir != Vector2.zero) { // 归一化处理避免斜向子弹移动速度比垂直方向快 shootDir.Normalize(); Quaternion bulletRot = Quaternion.LookRotation(Vector3.forward, shootDir); SpawnBullet(shootDir, bulletRot); currentTime = 0; } }
内容的提问来源于stack exchange,提问作者prosvade1337
相关产品推荐
相关产品推荐

