- Home /
Extremely confused with parent and child object system
So I was trying to understand the build mechanics for my game instead ended up having lots of questions about child and parent objects system. The script works fine but doesn't makes sense to me.
I will try to explain what I was trying to do:
- I have a prefab called m_slot which has a parent gameobject with rect transform and a child gameobject with button.   
- I have some sprites for sprite array 
- And a menu gameobject   
- This script is on Organelle Menu 
- It instantiates a slot and sets the parent to menu 
- But when I try to reach to the button gameobject it gets Slot with the name of the sprite which is for example "ribosome" (I noticed it by printing the name) 
 
Here is what I thought it should be like
- The _button should be the button game object instead it is Slot game object 
- So that I shouldn't be writing this 
_button.GetComponentInChildren().sprite = m_slotIcon[i]; _button.GetComponentInChildren().onClick.AddListener(OnClick);
but this
_button.GetComponent().sprite = m_slotIcon[i]; _button.GetComponent().onClick.AddListener(OnClick);
And I thought adding OnClick() function to the button would be the Button gameobjects function so when a I call its parent name it would give me the name of the slot which is "ribosome" for example
public class OrganelleMenu : MonoBehaviour {
 public GameObject m_slot;
 public Sprite[] m_slotIcon;
 private Transform m_menu;
 private void Awake()
 {
     m_menu = GameObject.FindGameObjectWithTag("OrganelleMenu").GetComponent<Transform>();
 }
 private void OnEnable()
 {
     for (int i = 0; i < m_slotIcon.Length; i++)
     {
         GameObject _slotInstance = Instantiate(m_slot, transform.position, Quaternion.identity);    //Instantiate slot
         _slotInstance.transform.SetParent(m_menu.transform);   //change slot parameters
         _slotInstance.transform.localScale = new Vector3(1, 1, 1);
         _slotInstance.name = m_slotIcon[i].name;
         GameObject _button =_slotInstance.GetComponentInChildren<Transform>().gameObject;
         Debug.Log(gameObject.name);
         Debug.Log(_button.name);
         _button.GetComponentInChildren<Image>().sprite = m_slotIcon[i];
         _button.GetComponentInChildren<Button>().onClick.AddListener(OnClick);
     }
 }
 void OnClick()
 {
     string _organelleName = GetComponentInParent<Transform>().name;
     Debug.Log("Clicked " + _organelleName);
 }
}
Any missing information please tell me. I have limited English knowledge. Tried my best
Answer by SirPaddow · Nov 02, 2019 at 08:29 PM
GetComponentInChildren will search for the component in the gameObject itself, then in its children and so on (https://docs.unity3d.com/ScriptReference/Component.GetComponentInChildren.html)
So, on line 20, when you try to get the Transform component on your children, you actually get the transform of "Slot" itself.
Assuming Slot does not have the "Button" component, you could fix it like this:
 Button _button =_slotInstance.GetComponentInChildren<Button>();
 Debug.Log(gameObject.name); // will still display "Slot"
 Debug.Log(_button.name); // will display "Button"
 _button.GetComponent<Image>().sprite = m_slotIcon[i];
 _button.onClick.AddListener(OnClick);
So all the getComponent commands(getComponentInParent, getComponentInChildren) are based on depth first search, right?
And is there any way to search for a specific component in childrens without the tags. For example:
- We have a empty gameobject and 3 child objects 
- But I want to reach to the third objects component 
I don't know all of them, but your two examples are indeed depth first search.
You can find most "strutcure" functions on the Transform Component (which all gameobjects have). As for your exemple, you could use GetChild like this:
 Transform my3rdChild = myGameObject.transform.GetChild(2);
I try to never use this kind of function though, because it's subject to so many errors. If in one month, you have to add a new child at the first position, this script won't work anymore and it will take a while to understand why. In your first example, I would create a "Slot" monobehaviour with a reference to the button, and assign this button through the inspector. It means that once my script is done, I will never have to come back to it anymore, and create any structure I want in Unity.
So you mean drag and drop method from the inspector is better than scripting.
I really appreciate the help. It really helped me understand better.
And before I forget, my approach with this kind of script was a more procedural method so that I won't need to worry about finding the components and so on. I wanted to just fill the array with the desired type and than the script will do the magic. But I guess there is no or at least I don't know how to, yet.
Your answer
 
 
             Follow this Question
Related Questions
Rotate Child with parent, keeping Child axis in the original direction 2 Answers
Make child's transform independent of parent 1 Answer
Snaping/Merging game objects together 0 Answers
Enabling/Deactivating objects using keys. 1 Answer
Why Deparenting The First Child Changes Position of The Parent 0 Answers
 koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                