What is the difference between GetComponent() and Find() in Unity?
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.
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:
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.
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!
- Database Administration Tutorials
- Programming Tutorials & IT News
- Linux & DevOps World
- Entertainment & General News
- Games & eSport