3
\$\begingroup\$

I'm just learning to develop in Unity. One simple thing I'd like to do is change the colors of objects programmatically. I have a compound asteroid prefab object, in which the meshrenderer and material is inside the child component asteroid_prop_01.

After reading the Unity docs and previous programming posts, I was able to do this successfully with GameObject.transform.Find(), but I don't understand why GameObject.Find(), GameObject.transform.Find() and GameObject.GetComponent() are not equivalent.

I'd really appreciate an understanding of the difference. E.g. all these methods are based on the particular GameObject instance assigned to clone, so why aren't they all returning the same specific instance of clone.prop_asteroid_01.renderer.material.color?

eGameObject clone = (GameObject) Instantiate (hazard, spawnPosition, spawnRotation);
// This works
clone.transform.Find("prop_asteroid_01").renderer.material.color = Color.blue;
// This fails at compile time: "Static member `UnityEngine.GameObject.Find(string)' cannot be accessed with an instance reference, qualify it with a type name instead"
clone.Find("prop_asteroid_01").renderer.material.color = Color.blue;
// Fails with runtime error "Object reference not set to an instance of an object"
clone.GetComponent("prop_asteroid_01").renderer.material.color = Color.blue;

Thanks for your help.

\$\endgroup\$
  • \$\begingroup\$ Have you read through the Scripting Reference docs for each of these three functions? \$\endgroup\$ – michael.bartnett Mar 29 '14 at 19:56
  • \$\begingroup\$ @michael.bartnett He read through the docs(as said above in his question), but the real problem is lack of a good definition and some confusion or perhaps unknown knowledge of technical terminology. We all know how confusing errors can be :-) \$\endgroup\$ – Grey Mar 30 '14 at 6:40
5
\$\begingroup\$

So GameObject.Find() and Transform.Find() are used to find an active game object, or child, within your scene(and in that respective order). Before we go any further, recognize the difference between a GameObject, Component, and the relationship between parents and children when using Unity.

Getting our Definitions Straight

Think of a GameObject as an empty container. You can fill this container with whatever you want. Let's say a MeshFilter and MeshRenderer. These are components. They are components of the object. Scripts? Those are components too(they are referred to as behavior components)! You can also attach other GameObjects to this game object creating a parent - child relationship and thus creating a hierarchy.

I kinda get it

Let me attempt to make this explanation a bit more easier to visualize:

Hierarchy:

Parent Object (Character)
       [   Transform     ] (Component)
       [   Mesh Renderer ] (Component)
       [   Mesh Filter   ] (Component)
       [ Movement Script ] (Behavior Component)
                          .../RHand (GameObject/Child/Prefab)
                          .../LHand (GameObject/Child/Prefab)
                          .../Eye   (GameObject/Child/Prefab)
                          .../RLeg  (GameObject/Child/Prefab)
                          .../LLeg  (GameObject/Child/Prefab)

So you have a GameObject. A container to store the children(GameObjects or Prefabs), the components(provided out of the box by Unity) and the behavior components that you make. The GameObject at the highest level is considered the parent and the objects that fall in line below are, you guessed it, child objects! Pretty simple concept to grasp, right?

OK, OK, but why doesn't that code run!?

Finding out why your code doesn't work is the first step to a solid understanding, besides having correct definitions of course! I'll start from the top.

You do:

GameObject clone = (GameObject) Instantiate (hazard, spawnPosition, spawnRotation);

You probably know why this works. You have a variable, clone, which is of type GameObject and you are "cloning" or "duplicating" the GameObject hazard into the clone variable. That's what Instantiate does. It makes a copy.

    // This fails at compile time: "Static member `UnityEngine.GameObject.Find(string)' 
    // cannot be accessed with an instance reference, qualify it with a 
    // type name instead"
    clone.Find("prop_asteroid_01").renderer.material.color = Color.blue;

Now would be a great time to talk about instance methods, and static methods. Static Methods can be accessed without having an initialized instance of said type. You just need the type name, and the correct function name and it will allow you to use it without error. What you're doing in this line is attempting to use a non-existent instance function. GameObject.Find is a static function, not an instance function! gameObject is an instance of GameObject. "GameObject" alone is the type, and can be used to access those static methods! Not only that - but this is the incorrect use of GameObject.Find. This particular function does not concern itself with child object. That is the job of transform.Find

// Fails with runtime error "Object reference not set to an instance of an object"
clone.GetComponent("prop_asteroid_01").renderer.material.color = Color.blue;

Remember those definitions? Is a component a gameObject(of course this varies from engine to engine, but we are talking about Unity). No! So what would you use to find the child of the parent object(clone)?? I told you in the paragraph above. Use transform.Find. This is not a static method, so it requires an instance of type Transform!

\$\endgroup\$
  • \$\begingroup\$ Thank you. This is helpful. I'll read some more about static methods next. \$\endgroup\$ – MikeA Mar 30 '14 at 20:53
  • \$\begingroup\$ @user43979 If this is solves the problem make sure to mark it as the answer =) \$\endgroup\$ – Grey Mar 30 '14 at 21:18
  • \$\begingroup\$ Yes, this is the answer. My main memory of the static keyword was from C, using it to ensure variables persist across function calls. Now static methods and members on objects make perfect sense to me. \$\endgroup\$ – MikeA Mar 30 '14 at 21:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.