没有GameObject.Find找到Gameobjects的更好方法

时间:2018-04-08 08:08:03

标签: c# unity3d optimization

使用Unity,我正在开发一款游戏,其中所有带有特定标签的Gameobjects都会定期消失/重新出现(平均每10秒)。我使用GameObject.FindGameObjectsWithTag()来创建Gameobject[],每当需要使对象变得可见/不可见时,我就会枚举Gameobjects。在开始时我无法调用一次,因为在播放时会创建新的Gameobject[]。我认为每次创建/销毁某些内容时访问和更改GameObject.Find会更糟。有没有更好的方法来处理这个问题。我知道{{1}}方法对性能的影响有多严重......

2 个答案:

答案 0 :(得分:6)

是的,有更好的方法可以做到这一点。拥有一个可以存储GameObjects的List变量的脚本。使它成为单身人士更好但不是必需的。

这个单例脚本应该附加到一个空的GameObject:

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);
    }
}

现在,编写一个脚本,将自己注册到List脚本中的GameObjectManager。它应该在Awake函数中注册自己,并在OnDestroy函数中取消注册。

此脚本必须附加到要添加到列表的每个预制件。只需从编辑那里做到:

public class GameObjectAutoAdd : MonoBehaviour
{
    void Awake()
    {
        //Add this GameObject to List when it is created
        GameObjectManager.instance.allObjects.Add(gameObject);
    }

    void OnDestroy()
    {
        //Remove this GameObject from the List when it is about to be destroyed
        GameObjectManager.instance.allObjects.Remove(gameObject);
    }
}

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

GameObject obj = new GameObject("Player");
obj.AddComponent<GameObjectAutoAdd>();

您现在可以使用GameObjects访问列表中的GameObjectManager.instance.allObjects[n];,其中n是索引编号,您不必使用Find中的任何一个用于找到GameObject的函数。

答案 1 :(得分:2)

调用GameObject.Find会消耗大量资源,这是真的。

重点应该是保存结果并始终使用它,但我知道你不能这样做。

其他选择是将所有这些游戏对象作为一个游戏对象的孩子,让它称之为handlerGameobject。它将有一个不使用GameObeject的脚本。找到它可以使用更少资源的getChild或transform.Find。

希望它有所帮助!