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

Getting components from children?(SOLVED)

Discussion in 'Scripting' started by tawdry, Jan 27, 2015.

  1. tawdry

    tawdry

    Joined:
    Sep 3, 2014
    Posts:
    1,356
    Hi guys
    trying to get component from children. Tried 3 ways but best result has been a null reference..

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class wizglow : MonoBehaviour {
    5.  
    6.     Animator dar;
    7.     NavMeshAgent duh;
    8.     float who;
    9.     GameObject de;
    10.     MeshRenderer mr;
    11.    
    12.     void Start(){
    13.                 de = GameObject.Find ("wizzyold");
    14.                 dar = de.GetComponent<Animator> ();
    15. 1    mr = de.GetComponent ("runes/runes01/Mesh").GetComponent < MeshRenderer> ();//null reference
    16.     2    mr = de.Find ("runes/runes01/Mesh").GetComponent<MeshRenderer> ();
    17. 3        mr = de.GetComponentsInChildren< MeshRenderer> ();
    18.     }
    19.  
    20.    
    21.    
    22.            
    23.    
    24. }
    The situation is i have a parent GO " wizzyold" with a GO "runes" with 26 runes01-26 each with a mesh renderer its that mesh rendere i want to get hold of.
    .
     
  2. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,500
    Is the parent the only GameObject called "wizzyold" in the scene?

    Also, you shouldn't be nesting GetComponent calls like you are on line 15. It looks like you're getting GameObjects and Components mixed up. GameObjects contain Components. It looks like your first call to GetComponent(...) on line 15 is actually trying to get a child GameObject with a given path.
     
  3. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,066
    Yeah - not quite on the right track there. Something more like:

    Code (csharp):
    1.  
    2. private void Start()
    3. {
    4.     de = GameObject.Find("wizzyold");
    5.     MeshRenderer[] meshRenderers = de.GetComponentsInChildren<MeshRenderer>();
    6.  
    7.     // I.E. AND THEN DO SOME STUFF WITH THEM
    8.     foreach (MeshRenderer thisMeshRenderer in meshRenderers)
    9.     {
    10.    
    11.     }
    12. }
    13.  
    ish...
     
    richardgomes7d and angrypenguin like this.
  4. tawdry

    tawdry

    Joined:
    Sep 3, 2014
    Posts:
    1,356
    I am trying to call a game object inside a gameobject inside a gameobject . I placed a empty game object(runes) in the original gameobject (wizzyold) then placed more gameobjects (runes1-26) in that gameobject and the component (mesh renderer is on that last gameobject (runes1-26) under Mesh..

    Ooooh you mean maybe i should be doing multiple gameobject .Finds?
     
  5. tawdry

    tawdry

    Joined:
    Sep 3, 2014
    Posts:
    1,356
    Hmm never seen this before I'll give it a go, see if I can figure through it. Thx
     
  6. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,500
    Or you can iterate over children via the Transform. There's a section in the manual about accessing GameObjects which goes over the different methods available if you haven't checked it out already.

    Or, you could make a serializable array in your script and put the runes in it in the Inspector.

    In any case, yeah, you get GameObjects and Components differently, where you're trying to get them the same way.
     
  7. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,066
    Like @angrypenguin said, it might also really depend on if there will just be one of these objects or more. For example, if there's just one - why reference the top level at all? You could jump right into the Runes something like:

    Code (csharp):
    1.  
    2. Transform runesTransform = GameObject.Find("runes").transform;
    3.  
    4. foreach (Transform thisChild in runesTransform)
    5. {
    6.     MeshRenderer thisMeshRenderer = thisChild.GetComponent<MeshRenderer>();
    7.  
    8.     if (thisMeshRenderer)
    9.     {
    10.         ...etc
    11.     }
    12. }
    13.  
     
    oranchad likes this.
  8. tawdry

    tawdry

    Joined:
    Sep 3, 2014
    Posts:
    1,356
    Not really so clued in on coding so those suggestion all make my head spin. Yea after I read your post It clicked that they were gameobjects i amended my script but still getting something wrong it does reference the right name now in the debug but not sure how to call the renderer.
     
  9. tawdry

    tawdry

    Joined:
    Sep 3, 2014
    Posts:
    1,356
    I have 26 objects inside 1 empty gameobject(runes) inside 1 parent and wish to call them individually.
     
  10. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,066
    That last script I posted should do the trick then.

    EDIT: Whether or not it's the BEST way to do it is up to smarter people than me though.
     
  11. tawdry

    tawdry

    Joined:
    Sep 3, 2014
    Posts:
    1,356
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class wizglow : MonoBehaviour {
    5.  
    6.     Animator dar;
    7.     NavMeshAgent duh;
    8.     float who;
    9.     GameObject de;
    10.     MeshRenderer mr;
    11.    
    12.     void Start(){
    13.     de = GameObject.Find("wizzyold/runes/runes01");
    14.                 dar = de.GetComponent<Animator> ();
    15.     ////mr = de.GetComponent ("wizzyold/runes/runes01/Mesh").GetComponent < MeshRenderer> ();//null reference
    16.         mr = de.GetComponent < MeshRenderer> ();
    17.         mr.Renderer = enabled;
    18.    
    19.    
    20.             de = GameObject.Find("wizzyold/runes/runes01");
    21.         MeshRenderer[] meshRenderers = de.GetComponentsInChildren<MeshRenderer>();
    22.         Debug.Log (de.name);
    23.             // I.E. AND THEN DO SOME STUFF WITH THEM
    24.             foreach (MeshRenderer thisMeshRenderer in meshRenderers)
    25.             {
    26.             enabled = true;//did not do anything.
    27.             }
    28.  
    29.  
    30.    
    31.     }
    32.  
    My latest clumsy attempts following the advice lol.
     
  12. tawdry

    tawdry

    Joined:
    Sep 3, 2014
    Posts:
    1,356
    Tried it just adding enabled=true but that didnt work so tried to path towards the correct gameobject but also no luck maybe the enabled=true line is not specific enough?
     
  13. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,066
    Code (csharp):
    1.  
    2. de =GameObject.Find("wizzyold/runes/runes01");
    3.  
    Why are you doing that? Do what I did in the script above :)
     
  14. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,066
    Also keep in mind that they're going to be enabled by default, right? So setting them enabled = true SHOULD have no effect, unless you've disabled them?
     
  15. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,500
    Also keep in mind that you have to specify what you're enabling. If you don't specify an object all you're doing is changing the enabled field on the current object... probably not what you want.
     
  16. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,066
    Also, why are you specifically accessing the MeshRenderer component? Do you just want to have them appear and disappear? If so, change that to just access the Renderer component.

    Out of curiosity, just try the below, switching enabled/disabled depending on what you want. I think you might be overcomplicating things and maybe this is all you're trying to do?

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class wizglow : MonoBehaviour
    6. {
    7.     private Transform _de;
    8.    
    9.     private void Start()
    10.     {
    11.         _de = GameObject.Find("runes").transform;
    12.  
    13.         foreach (Transform thisChild in _de)
    14.         {
    15.             Renderer thisRenderer = thisChild.GetComponent<Renderer>();
    16.          
    17.             if (thisRenderer)
    18.             {
    19.                 thisRenderer.enabled = false;
    20.             }
    21.         }  
    22.     }
    23. }
    24.  
     
  17. tawdry

    tawdry

    Joined:
    Sep 3, 2014
    Posts:
    1,356

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class wizglow : MonoBehaviour {
    5.     private Transform _de;
    6.     Animator dar;
    7.     NavMeshAgent duh;
    8.     float who;
    9.     //GameObject de;
    10.     MeshRenderer mr;
    11.    
    12.                
    13.     private void Start()
    14.             {
    15.                 _de = GameObject.Find("runes1").transform;
    16.                
    17.                 foreach (Transform thisChild in _de)
    18.                 {
    19.                     Renderer thisRenderer = thisChild.GetComponent<Renderer>();
    20.                    
    21.                     if (thisRenderer)
    22.                     {
    23.                         thisRenderer.enabled = false;
    24.                     }
    25.                 }
    26.             }
    27.         }
    28.  
    Hey Steve that did the trick I just had to change runes to runes1 to get the right directory. Unfortunately i don,t understand much of the code have to get my reading done on this. It does render them all and disable them all at the same time but need to do them one by one depending on a random number given. So if number =5 enable Mesh5 etc and no need to loop the rest but not sure how to do that within this code.
     
  18. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,066
    Hmm... you shouldn't have to change it to rune01 - "runes" should have worked as you want to iterate through all 26 of the child GameObjects under "runes" right?
     
  19. tawdry

    tawdry

    Joined:
    Sep 3, 2014
    Posts:
    1,356
    Runes is the empty game object under it there is another game object called runes 1 and it hold 26 meshes i could probably put them all under runes i guess and drop the middleman .
    Ok now all under runes but don't want to iterate through them all just need 1 active at any given time .
     
  20. tawdry

    tawdry

    Joined:
    Sep 3, 2014
    Posts:
    1,356
    Ok got it working like a need probably not the best thing to call Find in update sort that out later on.Thx

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class wizzy : MonoBehaviour {
    5.  
    6.         Animator dar;
    7.         NavMeshAgent duh;
    8.         float who;
    9.         GameObject de;
    10.         Renderer mr;
    11.     GameObject dea;
    12.     int a=0;
    13.  
    14.  
    15.     void Start(){
    16.                
    17.                 dar = GetComponent<Animator> ();//de
    18.                
    19.         }
    20.         void Update () {
    21.  
    22.  
    23.       a=Random.Range (1,22);
    24.         dea = GameObject.Find ("wizzyold/runes/Mesh"+a);
    25.         mr = dea.GetComponent < Renderer> ();
    26.         mr.renderer.enabled = true;
    27.         if (mr.renderer.enabled = true) {
    28.         //    mr.renderer.enabled = false;
    29.                 }
    30.     }}
     
  21. Sbizz

    Sbizz

    Joined:
    Oct 2, 2014
    Posts:
    250
    Code (CSharp):
    1. public class wizzy : MonoBehaviour {
    2.     Animator dar;
    3.     NavMeshAgent duh;
    4.     float who;
    5.     GameObject de;
    6.     Renderer mr;
    7.     Renderer[] dea;
    8.     int a=0;
    9.  
    10.     void Start() {
    11.         GameObject runes = GameObject.Find("wizzyold/runes");
    12.  
    13.         dar = GetComponent<Animator> ();//de
    14.         dea = runes.GetComponentsInChildren<Renderer>();
    15.     }
    16.  
    17.     void Update () {
    18.         // dea[a].enable = false; // Disable the previous mesh
    19.  
    20.         a = Random.Range (0, dea.Length - 1);
    21.  
    22.         dea[a].renderer.enabled = true;
    23.     }
    24. }
     
    tawdry likes this.
  22. tawdry

    tawdry

    Joined:
    Sep 3, 2014
    Posts:
    1,356
    Awesome thx mate much better than the code I would have ended up writing to optimize it:D
     
  23. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,066
    Just a quick note - you'll want:

    Code (csharp):
    1.  
    2. a = Random.Range(0, dea.Length);
    3.  
    As Random.Range excludes the max value with ints.
     
    angrypenguin likes this.
  24. Sbizz

    Sbizz

    Joined:
    Oct 2, 2014
    Posts:
    250
    Good to know ! lol.