Unity中如何在触发区域内通过InvokeRepeating实现定时发射炮弹?
解决Unity触发区域内才重复发射炮弹的问题
你的代码核心问题是:InvokeRepeating在Start()中直接启动,导致不管玩家是否处于触发区内,炮弹都会每3秒发射一次,isFiring变量完全没参与发射逻辑的判断,所以无法实现需求。
下面提供两种简洁的修复方案:
方案一:在发射方法中判断触发状态
改动最小的方式,直接在发射方法里加isFiring的判断,只有满足条件才执行发射:
public class FireProjectile : MonoBehaviour { public GameObject Player; public Transform launchPoint; public GameObject projectile; public float launchVelocity = 10f; public bool isFiring; void Start() { InvokeRepeating("fireProjectile", 0f, 3f); } void fireProjectile() { // 玩家不在触发区时直接返回,不发射 if (!isFiring) return; var _projectile = Instantiate(projectile, launchPoint.position, launchPoint.rotation); _projectile.GetComponent<Rigidbody>().velocity = launchPoint.forward * launchVelocity; } private void OnTriggerEnter(Collider other) { if (other.gameObject == Player) { isFiring = true; } } private void OnTriggerExit(Collider other) { if (other.gameObject == Player) { isFiring = false; } } }
这种方式的优点是改动极小,缺点是InvokeRepeating会一直后台运行,但每3秒一次的空判断几乎没有性能开销,适合简单场景。
方案二:触发时启动/停止重复调用
更高效的方式,仅在玩家进入触发区时启动发射,离开时立即停止,避免无用的重复执行:
public class FireProjectile : MonoBehaviour { public GameObject Player; public Transform launchPoint; public GameObject projectile; public float launchVelocity = 10f; void Start() { // 初始不启动发射逻辑 } void fireProjectile() { var _projectile = Instantiate(projectile, launchPoint.position, launchPoint.rotation); _projectile.GetComponent<Rigidbody>().velocity = launchPoint.forward * launchVelocity; } private void OnTriggerEnter(Collider other) { if (other.gameObject == Player) { // 防止重复触发导致发射频率异常,先判断是否已在运行 if (!IsInvoking("fireProjectile")) { InvokeRepeating("fireProjectile", 0f, 3f); } } } private void OnTriggerExit(Collider other) { if (other.gameObject == Player) { CancelInvoke("fireProjectile"); } } }
这种方式更符合逻辑设计,只有在需要的时候才运行发射逻辑,性能更优。
注意事项
- 确保触发区域的Collider组件勾选了Is Trigger,且玩家对象同时拥有Collider(非触发)和Rigidbody组件,否则
OnTriggerEnter/OnTriggerExit不会触发。
内容的提问来源于stack exchange,提问作者dangoqut132
相关产品推荐
相关产品推荐

