Unity C#开发移动端小游戏 如何正确实现游戏失败判定逻辑
原逻辑BUG原因
初始判定逻辑在子弹出膛扣减弹药的瞬间就执行「剩余弹药为0+平台存活=游戏失败」的判断,完全没有等待子弹完成飞行、碰撞检测的流程,因此最后一发出膛就会直接触发重启,即使这发子弹后续可以命中目标。
阈值判定方案实现
你提出的「所有已发射子弹超过y=5f阈值再判负」的逻辑完全可以解决该问题,实现时需要同时满足三个前置条件才会触发失败,避免误判:
- 玩家剩余可发射弹药数为0,不会再有新的子弹生成
- 场景内所有存活的已发射子弹y坐标均大于5f,全部飞过目标平台所在区域,不存在命中可能
- 场景内仍有未被摧毁的目标平台
具体实现步骤
- 提前给两类对象配置标签:给所有目标平台预制体贴
TargetPlatform标签,给所有子弹预制体贴Bullet标签 - 在全局GameManager脚本中编写核心逻辑,代码如下:
using UnityEngine; using UnityEngine.SceneManagement; public class GameManager : MonoBehaviour { [Header("关卡配置")] public int totalAmmo = 5; public float bulletFailThresholdY = 5f; private int _remainAmmo; private void Start() { _remainAmmo = totalAmmo; } /// <summary> /// 炮台发射时调用该方法,返回false代表无弹药无法射击 /// </summary> public bool Fire() { if (_remainAmmo <= 0) return false; _remainAmmo--; // 此处插入你已有的子弹生成、给子弹施加初速度的逻辑 return true; } private void FixedUpdate() { // 还有剩余弹药时跳过失败判定,玩家仍可射击新子弹 if (_remainAmmo > 0) return; // 所有目标平台已被摧毁,走通关逻辑,不判负 if (GameObject.FindGameObjectsWithTag("TargetPlatform").Length == 0) { // 此处插入你自己的通关结算逻辑 return; } // 遍历所有存活子弹,检查是否全部飞过阈值 GameObject[] aliveBullets = GameObject.FindGameObjectsWithTag("Bullet"); bool allBulletsPassThreshold = true; foreach (GameObject bullet in aliveBullets) { if (bullet.transform.position.y <= bulletFailThresholdY) { allBulletsPassThreshold = false; break; } } // 满足全部失败条件,重启场景 if (allBulletsPassThreshold) { SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex); } } }
注意事项
- 子弹命中目标、或者飞出屏幕上边界时必须调用
Destroy(gameObject)销毁,避免失效对象干扰判定,建议给子弹单独加个自动销毁逻辑:当自身y坐标超过bulletFailThresholdY + 1f时直接销毁,减少冗余对象开销 - 阈值y值建议比目标平台的最高y坐标高0.2~0.5f,抵消物理帧更新的时间差,避免子弹擦中平台前被误判为飞过阈值
- 该逻辑天然兼容多平台、多弹药的后续关卡配置,只要对应修改
totalAmmo和平台预制体数量即可,不需要改动核心判定代码
内容的提问来源于stack exchange,提问作者jlaw
相关产品推荐
相关产品推荐

