You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity 2D中如何检测GameObject列表内的对象是否已被销毁

Unity 战斗屏障存活敌人检测逻辑补全

需求背景

  • 维护GameObject类型的敌人列表,实现所有敌人被消灭前战斗屏障保持锁定的效果,敌人列表设置为public类型方便后续复用这套逻辑
  • 现有触发逻辑:玩家碰撞到屏障触发区域时,遍历敌人列表统计存活敌人数量:
    • 仍有敌人存活:启用战斗屏障碰撞体、切换为屏障显示精灵
    • 敌人全部被消灭:禁用屏障碰撞体、切换为无屏障的消失精灵
  • 待补全逻辑:for循环内的判断条件,需要检测列表中对应敌人GameObject是否已被销毁(引用失效、对象不存在/Inspector面板显示为None)

原有待补全代码

public GameObject fightBarrier;
public List<GameObject> enemies = new List<GameObject>();
public SpriteRenderer Barrier_0;
public SpriteRenderer Barrier_1;
public SpriteRenderer Barrier_2;
public SpriteRenderer Barrier_3;
public Sprite Barrier;
public Sprite noBarrier;

private int enemiesAmountCheck;

// overrided because it's inheriting from another script
protected override void OnCollide(Collider2D coll)
{
   if (coll.name == "Player")
   {
      enemiesAmountCheck = enemies.Count;
      for (int i = 0; i < enemies.Count - 1; i++)
      {
         // This if statement has to check if the GameObject doesn't exist (AKA the GameObject is None)
         if (enemies[i]... )
         {
            enemiesAmountCheck = enemiesAmountCheck - 1;
         }
      }
      if (enemiesAmountCheck > 0)
      {
         fightBarrier.GetComponent<BoxCollider2D>().enabled = true;
         Barrier_0.sprite = Barrier;
         Barrier_1.sprite = Barrier;
         Barrier_2.sprite = Barrier;
         Barrier_3.sprite = Barrier;
      }
      else
      {
         fightBarrier.GetComponent<BoxCollider2D>().enabled = false;
         Barrier_0.sprite = noBarrier;
         Barrier_1.sprite = noBarrier;
         Barrier_2.sprite = noBarrier;
         Barrier_3.sprite = noBarrier;
      }
   }
}

补全方案

核心判断条件

Unity对UnityEngine.Object(GameObject的直接基类)重载了==运算符,直接判断enemies[i] == null即可同时覆盖两种失效场景:

  • 列表元素本身未在Inspector面板赋值,对应字段显示为None
  • 敌人GameObject已经被Destroy()方法销毁,引擎原生层对象已释放

补全后的if判断为:

if (enemies[i] == null)
{
    enemiesAmountCheck--;
}

原有代码bug修复

原for循环的边界条件写为i < enemies.Count - 1,会漏掉列表最后一个敌人的检测,需要修改为i < enemies.Count才能遍历所有列表元素,否则会出现敌人全灭但屏障仍锁定的异常。

补全后完整逻辑代码

public GameObject fightBarrier;
public List<GameObject> enemies = new List<GameObject>();
public SpriteRenderer Barrier_0;
public SpriteRenderer Barrier_1;
public SpriteRenderer Barrier_2;
public SpriteRenderer Barrier_3;
public Sprite Barrier;
public Sprite noBarrier;

private int enemiesAmountCheck;

// overrided because it's inheriting from another script
protected override void OnCollide(Collider2D coll)
{
   if (coll.name == "Player")
   {
      enemiesAmountCheck = enemies.Count;
      // 修复循环边界,遍历所有敌人条目
      for (int i = 0; i < enemies.Count; i++)
      {
         // 检测敌人对象是否未赋值/已被销毁
         if (enemies[i] == null)
         {
            enemiesAmountCheck--;
         }
      }
      if (enemiesAmountCheck > 0)
      {
         fightBarrier.GetComponent<BoxCollider2D>().enabled = true;
         Barrier_0.sprite = Barrier;
         Barrier_1.sprite = Barrier;
         Barrier_2.sprite = Barrier;
         Barrier_3.sprite = Barrier;
      }
      else
      {
         fightBarrier.GetComponent<BoxCollider2D>().enabled = false;
         Barrier_0.sprite = noBarrier;
         Barrier_1.sprite = noBarrier;
         Barrier_2.sprite = noBarrier;
         Barrier_3.sprite = noBarrier;
         // 可选优化:清空列表内的空引用,避免后续重复遍历无效元素
         enemies.RemoveAll(enemy => enemy == null);
      }
   }
}

优化说明:检测到所有敌人被消灭后,可以调用enemies.RemoveAll(enemy => enemy == null)清理列表里的空引用,避免后续触发检测时重复遍历已销毁的无效元素,减少不必要的性能消耗。

内容的提问来源于stack exchange,提问作者Anthony Ruiz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 08:27:42