Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

What's the difference between GetComponent and FindObjectsOfType?

Discussion in 'Scripting' started by KokodokoGames, Aug 17, 2020.

  1. KokodokoGames

    KokodokoGames

    Joined:
    May 20, 2014
    Posts:
    40
    I'm confused about the difference between FindObjectsOfType and GetComponent<Type>

    I'm creating a UI that has Toggles. I add them to the scene via Add > UI > Toggle. From script I access all my Toggles using FindGameObjects:

    Code (CSharp):
    1. allToggles = GameObject.FindObjectsOfType(typeof(Toggle)) as Toggle[];
    2. foreach (Toggle go in allToggles) {
    3.    Debug.Log("checked: " + go.isOn);
    4. }
    This works, but I found GameObjects, not Components, right?

    So why does it say in the documentation, and many other code examples, that you have to use GetComponent<Toggle>(); to find the component on the gameobject? This code is from the Unity documentation:

    Code (CSharp):
    1. public class Example : MonoBehaviour
    2. {
    3.     Toggle m_Toggle;
    4.     void Start()
    5.     {
    6.         //Fetch the Toggle GameObject
    7.         m_Toggle = GetComponent<Toggle>();
    8.     }
    9. }
    Does a Toggle GameObject HAVE a Toggle Component? Or IS it a component ???
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    Nope, FindObjectOfType can directly find components. It's a really slow and inefficient function, but it can directly find components.

    That example simply shows how to get a component on the same GameObject as that script. It doesn't say that you have to do anything.

    GameObjects are just bags of components. They never are components.

    FindObjectOfType is like "Is there any object of this type in the whole game right now?". Then it searches the whole world to answer that question. GetComponent just searches a single GameObject.

    Note the difference between "object" and "GameObject".
     
  3. seejayjames

    seejayjames

    Joined:
    Jan 28, 2013
    Posts:
    685
    This has confused me too, especially with the UI gameObjects/components. If you choose GameObject--UI--Text, that shows up as a gameObject in the hierarchy. All good. However, that gameObject has a Text *component* on it. So, yeah...
     
    KokodokoGames likes this.
  4. KokodokoGames

    KokodokoGames

    Joined:
    May 20, 2014
    Posts:
    40
    Exactly! And when you have a public variable for a component, you drag a GameObject on the field, not a component! But even then you can manipulate it directly. For example:
    Code (CSharp):
    1. public Text myField;
    2.  
    3. void Start(){
    4.    myField.text = "Hello";
    5. }
    I didn't have to look for the text component using GetComponent<Text>();
     
  5. Ardenian

    Ardenian

    Joined:
    Dec 7, 2016
    Posts:
    313
    Yesn't. If you drag a GameObject into a field that serializes a reference to a component, Unity looks up all the components on that GameObject and chooses the one that matches the type of the component for that field. Try dragging a GameObject into such a field that has not the required component. Unity should either refuse to let you drag it into that field or add the component to the GameObject.

    As for the difference of GetComponent<T> and FindObjectsOfType<T>, think about a multi-party house with all parties sharing the same furniture, inlcuding a coffee machine. Every party has their own coffee machine as part of their furniture. Your furniture is your GameObject. If you call GetComponent<T> on your furniture with T representing your coffee machine, you get exactly one coffee machine, your coffee machine from your furniture. If you call FindObjectsOfType<T>, that's like knocking on the door of all of the other parties in your house and asking to see and grab their coffee machine.
     
  6. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    My opinion is if you find yourself needing FindObjectsOfType then you're facing a problem of bad design on your end. As already mentioned it is slow, but additionally it can lead to later hard to find bugs.

    For example, say you're using it as in the OP to find all Toggles and turn them all on. It works fine. Then 6 months later someone else working on your project adds a new Toggle, and wants it to start in the off state. But they find it keeps turning on for seemingly no reason, even though they just added it, it starts in the off state, and nothing else in the project references it. Might take them half a day to find the source of the problem with your FindObjectsOfType call.

    It would be better to just turn on the specific Toggles you want to turn on, instead of affecting all Toggles globally, to avoid issues later on. Direct references to the Toggles would be better, or references to the GameObjects and then using GetComponent, instead of using FindObjectsOfType. My opinion at least.
     
    KokodokoGames likes this.