Search Unity

[C#] trying to access all children with tag (diffrent game objects)

Discussion in 'Scripting' started by RyanSyg, Sep 18, 2014.

  1. RyanSyg

    RyanSyg

    Joined:
    Nov 2, 2012
    Posts:
    17
    I'm trying to fake shadows on a 2d sprite game by duplicating the sprite and changing the color. So, i have a few game object with children on them and these children have the tag "Shadow". What I'd like to do is from a script (on a completely different gameobject) is disable/enable the renderer.

    Code (CSharp):
    1.  
    2. public class Shadow : MonoBehaviour
    3. {
    4.     public GameObject[] shadows;
    5.     void Awake()
    6.     {
    7.         if(shadows == null)
    8.         {
    9.         shadows = GameObject.FindGameObjectsWithTag("Shadow");
    10.         }
    11.     }
    12.  
    13.     void Update()
    14.     {
    15.         if(GameManager.Instance.shadowsOn)
    16.             {
    17.                 foreach(GameObject shadow in shadows)
    18.                 {
    19.                 shadow.renderer.enabled = true;
    20.                 }
    21.             }
    22.         else
    23.         {
    24.             foreach(GameObject shadow in shadows)
    25.             {
    26.                 shadow.renderer.enabled = false;
    27.             }
    28.         }
    29.  
    30. //        if(!GameManager.Instance.shadowsOn)
    31. //        {
    32. //            gameObject.renderer.enabled = true;
    33. //        }
    34. //        else
    35. //        {
    36. //            gameObject.renderer.enabled = false;
    37. //        }
    38.     }
    39.  
    40. }
    The part that is commented out is my working script. But I have to have it placed on every Shadow gameobject.

    If I run this script now my public GameObject[] shadows is 0. If checked the tags and they are correct.

    bellow is a picture of my Hierarchy to help with my explanation.


    Thanks for any help.

    Ryan S.
     
  2. Limeoats

    Limeoats

    Joined:
    Aug 6, 2014
    Posts:
    104
    Hi Ryan.
    Your issue actually stumped me for quite awhile. I looked over your code multiple times and could not figure out what could possibly be wrong with it.
    I believe your issue is that you're doing this:
    Code (CSharp):
    1. if(shadows == null)
    2. {
    3.     shadows = GameObject.FindGameObjectsWithTag("Shadow");
    4. }
    ..in the "Awake" function rather than the "Start" function.
    The problem is that at the time this particular Awake method is being invoked, there is no guarantee that your other objects have been awoken yet.

    From now on, use Awake to initialize things within that own class only. You cannot rely on other classes when you are in an Awake method.

    So, to solve your issue, simply change Awake to Start.
    The Start method will be invoked only on active objects, but it will happen once everything else is already awoken. This will guarantee that the other objects will be ready when that code is executed.

    Hope this helps and good luck.
     
    RyanSyg likes this.
  3. RyanSyg

    RyanSyg

    Joined:
    Nov 2, 2012
    Posts:
    17
    That didn't quite work but it did give me an idea that seems to fix it.

    for starters I needed to change:
    Code (CSharp):
    1.  
    2. public GameObject[] shadows;
    3.  
    4. to
    5.  
    6. private GameObject[] shadows;
    then I moved the call to Start() like you suggested. Works now.

    I also had to add:
    shadows = GameObject.FindGameObjectsWithTag("Shadow");

    to the update as well. Since I was instantiating a gameobject with a shadow.

    Thank you for helping me solve my issue.
     
  4. Limeoats

    Limeoats

    Joined:
    Aug 6, 2014
    Posts:
    104
    I'm glad I could help!