C# 在没有游戏对象的情况下查找游戏对象的更好方法。查找

C# 在没有游戏对象的情况下查找游戏对象的更好方法。查找,c#,unity3d,optimization,C#,Unity3d,Optimization,使用Unity,我正在开发一款游戏,其中所有带有特定标记的游戏对象都会非常有规律地消失/重新出现(平均每10秒一次)。我使用GameObject.FindGameObjectsWithTag()创建一个GameObject[],每次需要使对象可见/不可见时,我都通过它来枚举。我不能一开始就调用它,因为新的游戏对象是在玩游戏时创建的。我认为每次有东西被创建/破坏时,访问和更改Gameobject[]会更糟糕。有没有更好的方法来处理这个问题。我知道调用GameObject.Find会对性能造成多大的

使用Unity,我正在开发一款游戏,其中所有带有特定标记的
游戏对象都会非常有规律地消失/重新出现(平均每10秒一次)。我使用
GameObject.FindGameObjectsWithTag()
创建一个
GameObject[]
,每次需要使对象可见/不可见时,我都通过它来枚举。我不能一开始就调用它,因为新的
游戏对象是在玩游戏时创建的。我认为每次有东西被创建/破坏时,访问和更改
Gameobject[]
会更糟糕。有没有更好的方法来处理这个问题。我知道调用GameObject.Find会对性能造成多大的影响。

调用GameObject.Find确实会消耗大量资源

重点应该是保存结果并始终使用它,但我理解您不能这样做

另一种选择是将所有这些游戏对象作为一个游戏对象的子对象,我们称之为handlerGameobject。它将有一个不使用GameObject的脚本。Find可以获取子对象或转换。Find使用更少的资源


希望有帮助

是的,有更好的方法。有一个带有
List
变量的脚本,可以存储游戏对象。让它成为单身汉更好,但不是必须的

此单例脚本应附加到空游戏对象:

public class GameObjectManager : MonoBehaviour
{
    //Holds instance of GameObjectManager
    public static GameObjectManager instance = null;
    public List<GameObject> allObjects = new List<GameObject>();

    void Awake()
    {
        //If this script does not exit already, use this current instance
        if (instance == null)
            instance = this;

        //If this script already exit, DESTROY this current instance
        else if (instance != this)
            Destroy(gameObject);
    }
}

如果游戏对象不是预制的,而是通过代码创建的游戏对象,只需在创建后将
GameObjectAutoAdd
脚本附加到它们:

GameObject obj = new GameObject("Player");
obj.AddComponent<GameObjectAutoAdd>();
gameobjectobj=新游戏对象(“玩家”);
obj.AddComponent();

您现在可以使用
GameObjectManager.instance.allObjects[n]访问列表中的
GameObjects
其中
n
是索引号,您不必再使用任何
Find
函数来查找游戏对象

非常感谢!这确实有帮助。@Chopi你需要15个代表才能投票。OP是新的,还没有那个代表,所以不能升级投票。尽管如此,他/她可以接受他/她已经做过的回答。我非常感谢你们。这解决了我所有的问题!你解释得再好不过了。我衷心感谢你,不客气。顺便说一句,我在
ondestory
函数中的回答有一个输入错误,我使用了List
Add
函数而不是
Remove
函数。
Add
功能只能在
Awake
功能中使用。我刚修好。确保更新代码。通常我更喜欢在
Start
中执行外部引用操作,而不是
Awake
,除非事先制定了非常具体的脚本执行顺序。@Galandil我理解你的意思。不知道要将代码放入哪个函数可能会导致变量在使用前未初始化等问题。尽管如此,我还是花了几分钟决定在
Awake
Start
OnEnable
之间使用哪一个,并决定使用
Awake
。此决定背后的两个原因是:1.即使脚本被禁用,也会调用
Awake
函数。如果不这样做,脚本将不会在禁用时注册自身。2.
Awake
函数将在注册它的第一个帧中被调用,以便可以在其他脚本的
Start
更新中使用。我的坏消息!一定是因为没有点击
GameObject obj = new GameObject("Player");
obj.AddComponent<GameObjectAutoAdd>();