GameObject.FindObjectOfType<>() 与 GetComponent<>()

GameObject.FindObjectOfType<>() vs GetComponent<>()

我一直在关注几个教程系列,看到这两个的使用方式非常相似,希望有人能解释它们的不同之处,如果可能的话,举例说明何时使用一个而不是另一个(假设他们实际上很相似!)。

private LevelManager levelManager;

void Start () {
    levelManager = GameObject.FindObjectOfType<LevelManager>();
}

private LevelManager levelManager;

void Start () {
    levelManager = GetComponent<LevelManager>();
}

有两点不同:

1.) GetComponent<T> 仅当组件附加到同一个 GameObject 时才查找该组件。另一方面,GameObject.FindObjectOfType<T> 搜索整个层次结构,returns 第一个匹配的对象!

2.) GetComponent<T> returns 只是一个继承自 Component 的对象,而 GameObject.FindObjectOfType<T> 并不关心。

您不想使用

void Start () {
    levelManager = GameObject.FindObjectOfType<LevelManager>();
}

经常。特别是 start

不过要回答你的问题,这两个函数实际上并不是很相似。一个是外部调用,一个是内部调用。
那么有什么区别呢?

  1. GameObject.FindObjectOfType 更像是一个场景范围的搜索,并不是获得答案的最佳方式。其实Unity公开表示超级慢 Unity3D API Reference - FindObjectOfType

  2. GetComponent<LevelManager>();是本地电话。这意味着进行此调用的任何文件都只会搜索它所附加的游戏对象。所以在检查器中,文件只会搜索同一个检查器中的其他东西window。比如Mesh Renderer,Mesh Filter,等等。或者说objects children。不过,我相信对此有单独的呼吁。
    此外,如果您首先引用它们,则可以使用它来访问其他 GameObject 的组件(如下所示)。

分辨率:

我建议在 awake 函数中进行 tag 搜索。

private LevelManager levelManager;

void Awake () {
    levelManager = GameObject.FindGameObjectWithTag ("manager").GetComponent<LevelManager>();
}

不要忘记通过添加标签来标记带有脚本 LevelManager 的 GameObject。 (点击GameObject,查看inspector上方,点击Tag->Add Tag

你可以这样做,或者

public LevelManager levelManager;

并将 GameObject 拖入检查器中的框中。

这两种选择都明显优于 GameObject.FindObjectOfType

希望对您有所帮助