如何用C#脚本查找Unity场景中未激活的游戏对象?
查找场景中包含未激活对象的同标签游戏对象数组
Unity自带的FindGameObjectsByTag()确实只返回激活状态的游戏对象,要获取包括未激活的同标签对象,可以用以下两种实用方案:
方案1:用Resources.FindObjectsOfTypeAll过滤查找
这个API会返回所有已加载的指定类型对象(包括未激活、甚至资源里的预制体),所以需要添加额外条件过滤出场景中的目标对象:
using UnityEngine; public static class GameObjectExtensions { public static GameObject[] FindAllGameObjectsByTag(string tag) { // 获取所有已加载的GameObject(包括未激活) GameObject[] allObjects = Resources.FindObjectsOfTypeAll<GameObject>(); // 过滤出标签匹配、且是场景中的对象(排除预制体/资源) System.Collections.Generic.List<GameObject> result = new System.Collections.Generic.List<GameObject>(); foreach (GameObject obj in allObjects) { if (obj.CompareTag(tag) && !string.IsNullOrEmpty(obj.scene.name)) { result.Add(obj); } } return result.ToArray(); } }
使用方式直接调用:
GameObject[] allTaggedObjects = GameObjectExtensions.FindAllGameObjectsByTag("YourTag");
注意:这个方法性能开销较大,因为会遍历所有已加载对象,适合编辑器工具或者运行时偶尔一次性查找的场景,不适合帧调用。
方案2:提前注册(高效推荐)
如果场景中的目标对象是固定的,推荐在每个目标对象的脚本里,在Awake()(即使对象未激活也会执行Awake)时主动注册到全局数组中:
using UnityEngine; using System.Collections.Generic; public class TaggedObjectRegister : MonoBehaviour { public static List<GameObject> taggedObjects = new List<GameObject>(); public string targetTag; void Awake() { // 只有标签匹配才注册 if (gameObject.CompareTag(targetTag)) { taggedObjects.Add(gameObject); } } void OnDestroy() { // 对象销毁时移除,避免空引用 if (gameObject.CompareTag(targetTag)) { taggedObjects.Remove(gameObject); } } }
使用时,给所有需要被查找的对象(包括未激活的)挂载这个脚本,设置好targetTag,之后直接访问TaggedObjectRegister.taggedObjects就能拿到所有同标签对象(包括未激活)。
这种方式性能最优,适合运行时频繁访问的场景,避免每次查找的遍历开销。
内容的提问来源于stack exchange,提问作者user22366277
相关产品推荐
相关产品推荐

