Balloon Fight类游戏碰撞优化:仅触发距离最近的气球碰撞
优化气球碰撞逻辑,优先销毁最近的气球
你的问题在于OnTriggerEnter会在同一帧内触发多个气球的碰撞回调,而isAttacking的锁只能随机阻止后续触发,没法保证选中最近的气球。要解决这个问题,我们需要先收集所有符合条件的碰撞气球,再在帧末筛选出最近的那个处理,具体实现如下:
修改思路
- 不在
OnTriggerEnter里直接销毁气球,改为收集当前帧内所有触发的有效气球 - 在
LateUpdate中遍历收集到的气球,计算每个气球到攻击角色的距离,选出最近的那个进行销毁 - 处理完成后清空列表,确保下一帧可以重新收集
修改后的代码
// 存储当前帧内触发的所有有效气球 private List<GameObject> triggeredBalloons = new List<GameObject>(); private void OnTriggerEnter(Collider collision) { GameObject balloon = collision.gameObject; // 检查图层和标签是否符合条件 if (balloon.layer == 7 && balloon.tag != this.gameObject.tag) { triggeredBalloons.Add(balloon); } } void LateUpdate() { if (triggeredBalloons.Count > 0) { // 找到距离当前角色最近的气球 GameObject closestBalloon = null; float minDistance = float.MaxValue; Transform attackTransform = transform.parent; // 攻击角色的Transform foreach (var balloon in triggeredBalloons) { if (balloon == null) continue; // 防止已销毁的对象干扰 float distance = Vector3.Distance(attackTransform.position, balloon.transform.position); if (distance < minDistance) { minDistance = distance; closestBalloon = balloon; } } // 处理最近的气球 if (closestBalloon != null) { Destroy(closestBalloon.transform.parent.gameObject); attackTransform.GetComponent<Jump>().jump = true; } // 清空列表,准备下一帧收集 triggeredBalloons.Clear(); } }
关键优化点
- 减少冗余操作:去掉原代码中重复的
collision.GetComponent<Collider>()调用,直接使用collision.gameObject更高效 - 帧末统一处理:利用
LateUpdate在所有OnTriggerEnter回调执行完毕后再处理,确保能收集到同一帧内的所有触发气球 - 精准距离判断:以攻击角色的位置为基准计算每个气球的距离,确保选中最近的目标
这样修改后,就能保证每次只会销毁距离攻击角色最近的那个气球,同时避免同一帧内破坏多个气球的问题。
内容的提问来源于stack exchange,提问作者jooji
相关产品推荐
相关产品推荐

