23

I have been following several tutorial series and have seen these two used in very similar ways, and was hoping someone could explain how they differ and, if possible, examples of when you would use one instead of the other (presuming that they are actually similar!).

private LevelManager levelManager;

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

and

private LevelManager levelManager;

void Start () {
    levelManager = GetComponent<LevelManager>();
}
JonHerbert
  • 647
  • 1
  • 8
  • 23

2 Answers2

28

You don't want to use

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

that often. Particularly on start

To answer your question though, these two functions are actually not very similar. One is a exterior call, the other an interior.
So what's the difference?

  1. The GameObject.FindObjectOfType is more of a scene wide search and isn't the optimal way of getting an answer. Actually, Unity publicly said its super slow Unity3D API Reference - FindObjectOfType

  2. The GetComponent<LevelManager>(); is a local call. Meaning whatever file is making this call will only search the GameObject that it is attached to. So in the inspector, the file will only search other things in the same inspector window. Such as Mesh Renderer, Mesh Filter, Etc. Or that objects children. I believe there is a separate call for this, though.
    Also, you can use this to access other GameObject's components if you reference them first (show below).

Resolution:

I would recommend doing a tag search in the awake function.

private LevelManager levelManager;

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

Don't forget to tag the GameObject with the script LevelManager on it by adding a tag. (Click the GameObject, look at the top of the inspector, and click Tag->Add Tag

You can do that, or do

public LevelManager levelManager;

And drag the GameObject into the box in the inspector.

Either option is significantly better than doing a GameObject.FindObjectOfType.

Hope this helps

iSkore
  • 7,394
  • 3
  • 34
  • 59
7

There are two differences:

1.) GetComponent<T> finds a component only if it's attached to the same GameObject. GameObject.FindObjectOfType<T> on the other hand searches whole hierarchy and returns the first object that matches!

2.) GetComponent<T> returns only an object that inherits from Component, while GameObject.FindObjectOfType<T> doesn't really care.

walther
  • 13,466
  • 5
  • 41
  • 67
  • 1
    @Kryptos, what do you mean by `Object`? `GetComponent`? That will return the first component, which is most probably a MonoBehaviour and it's still inheriting from `Component`. – walther May 18 '15 at 19:17
  • 1
    Interestingly `GetComponent` will return the first component of the `GameObject` (which should always be the `Transform`). Also note that `FindObjectOfType` is not defined in `GameObject` but in `Object` (which is the root class for any other class in Unity API) so you can find actually anything with it. – Kryptos May 18 '15 at 19:18
  • 1
    @Kryptos, I guess `Transform` is a special type of component, because you can't remove it, so maybe that's why it gets omitted by `GetComponent`. Probably no one will ever try to reference a transform (or any other component to be honest) by GetComponent anyway. – walther May 18 '15 at 19:27