Search Unity

How to get gameobjects that inside instantiated prefabs?

Discussion in 'Scripting' started by ndmrzk, Mar 6, 2020.

  1. ndmrzk

    ndmrzk

    Joined:
    Jul 25, 2018
    Posts:
    35
    Hello, i think im confusing myself on this. I have a scrollview which i then instantiate gameobjects to it on a button click. in that instantiated prefab, it also has its own scrollview which then i want to access the contents and put the contents in a list. the hierarchy is like :

    Code (CSharp):
    1. ScrollView
    2. -Content
    3.    - instantiated prefabs
    4.      - scrollview
    5.        - content
    6.          - gameobjects i want to access (there are 8 of these)
    7.    - instantiated prefabs
    8.      - scrollview
    9.        - content
    10.          - gameobjects i want to access (there are 8 of these)
    11.  
    I want to put the found gameobjects into a list. then im going to loop through them to find text fields and assign values to each of them. i instantiate like this :

    Code (CSharp):
    1. //Instantiare the Logs
    2. for (int i = 0; i < analysisFull.list.Count; i++)
    3. {
    4.     GameObject newLog = Instantiate(DailyLogPrefab, new Vector3(0, 0, 0), Quaternion.identity);
    5.     newLog.transform.SetParent(LogViewContent);
    6.     newLog.transform.localScale = Vector3.one;
    7. }
    then i was thinking in the forloop :

    Code (CSharp):
    1. ContentSizeFitter csf = newLog.GetComponentInChildren<ContentSizeFitter>();
    2.  
    3. Image img = csf.GetComponentInChildren<Image>();
    4.  
    5. Results.Add(img);
     
  2. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    Two ways come to my mind:
    1. If the prefab does not change, you could 'hardcode' the child indices to get to the parent of your 8 GameObjects, ie newPrefab.transform.GetChild(3).transform.GetChild(0)... - then save all childrens of this object. At least, if i understood you correctly, all 8 gameobject share the same direct parent, so you'd only need to 'hardcode' one path. Getting those components would then be pretty efficient, but not very robust since it relies on the prefab hierarchy not changing in the future (which is a hard promise to make most of the time).
    2. You could attach some empty component (your own script) to the gameobject you want to find, then use GetComponentsInChildren<YourComponent> to find all of those gameobjects. This would directly return you the correct gameobjects. This would be a bit less efficient, since Unity has to iterate over all children to find the correct ones, as far as i know, but unless your Prefabs are very large or you instantiate tons of them it should be fine.
    Whatever you do, only do it once. Save the result in a list and never do it again for this prefab. Doing it constantly would be unnecessary and hurt performance.

    Hope this helps :)
     
    ndmrzk and Kurt-Dekker like this.
  3. ndmrzk

    ndmrzk

    Joined:
    Jul 25, 2018
    Posts:
    35
    thanks @Yoreki !

    So i'm trying your first suggestion. my code looks like this (shortened it) :

    Code (CSharp):
    1. for (int i = 0; i < analysisFull.list.Count; i++)
    2. {
    3.     GameObject newLog = Instantiate(DailyLogPrefab, new Vector3(0, 0, 0), Quaternion.identity);
    4.     newLog.transform.SetParent(LogViewContent);
    5.     newLog.transform.localScale = Vector3.one;
    6.  
    7.     foreach (var item in analysisFull.list)
    8.     {
    9.         string circle = item.result.circles;
    10.         string red = item.result.redness;
    11.         string texture = item.result.skin_texture;
    12.    
    13.        newLog.transform.GetChild(3).GetChild(0).GetComponentInChildren<TMP_Text>().text = cricle;
    14.        newLog.transform.GetChild(3).GetChild(1).GetComponentInChildren<TMP_Text>().text = red;
    15.        newLog.transform.GetChild(3).GetChild(2).GetComponentInChildren<TMP_Text>().text = textuer;
    16.      }
    17. }

    but my indexing is wrong somewhere because unity says my transform child is out of bounds. the hierarchy is:

    Code (CSharp):
    1. LogView
    2.     - Viewport
    3.         - content
    4.             -instantiated prefab which is a scrollview
    5.                 - photo
    6.                 - Scrollview
    7.                     - viewport
    8.                        - content
    9.                             - parent
    10.                                 -child that has tmp_text that i want to access
    11.                             - parent
    12.                                 -child that has tmp_text that i want to access
    13.                             - there are  more parents
    14.  
     
  4. ndmrzk

    ndmrzk

    Joined:
    Jul 25, 2018
    Posts:
    35
    my index was wrong, actually the index is like:

    Code (CSharp):
    1. newLog.transform.GetChild(1).GetChild(0).GetChild(0).GetChild(0).GetComponentInChildren<TMP_Text>().text = circle
    prefab > photo(0) > scrollview(1) > viewport(0) > content(0) > parent(0) > getcomponentinchildren
     
  5. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    Does it work now, or are there still any open questions? :)
     
  6. ndmrzk

    ndmrzk

    Joined:
    Jul 25, 2018
    Posts:
    35
    Yes it does. Thank you!