Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by oxidedivision · Feb 06, 2019 at 01:38 AM · getcomponentawakedependencies

GetComponentInChildren returns null during Awake()

I'm having some trouble trying to maintain a referenceto my Controller class from each of my other classes. I'm trying to maintain this reference by calling GetComponentInParent during the Awake method, however this returns null. If I call it during the Start method, it returns as would be expected.


Say I have two objects in my Scene:


  • Controller (parent)

  • Player (child)


 public class Controller : MonoBehaviour 
 {
     private Player _player;
     
     private void Awake()
     {
         // Gets the object as expected
         _player = GetComponentInChildren<Player>();
     }
 }

 public class Player : MonoBehaviour
 {
     private Controller _controller;
     
     private void Awake()
     {
         // fails to get the object, returns null
         _controller = GetComponentInParent<Controller>();
     }
     
     private void Start()
     {
         // gets the object
         if (_controller == null)
             _controller = GetComponentInParent<Controller>();
     }
 }


During the Player.Awake() call, the Controller component cannot be found, and returns null. However, in the Player.Start() call, it's found.


I really want to link up my dependencies during the Awake function for all classes - how can I achieve this?


Thanks!



Note: My script execution order dictates that the Controller script will run before the Player script, and this is visually confirmed while the debugger is attached to Unity.

Comment
Add comment · Show 6
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Casiell · Feb 06, 2019 at 07:57 AM 2
Share

The way Unity starts up, it is not really a good idea to do that. Use Awake for internal initialization and Start for anything that has to do with other objects

avatar image fafase · Feb 06, 2019 at 08:07 AM 0
Share

Why would you need it in Awake?

avatar image Bonfire-Boy · Feb 06, 2019 at 08:55 AM 1
Share

Agree with the other comments. This seems a strange way of doing things. Your controller only controls things that are its direct children? If the objects are set up in the scene when you load it, you can connect them in the inspector. If they're instantiated in code, connect them after instantiating them.

But also, this looks like a one-to-one relationship. If so, why do you need to find it twice...?

 public class Controller : $$anonymous$$onoBehaviour 
  {
      private Player _player;
      
      private void Awake()
      {
          // Gets the object as expected
          _player = GetComponentInChildren<Player>();
          _player.controller = this;
      }
  }

I really want to link up my dependencies during the Awake function for all classes

$$anonymous$$aybe if you could explain what makes you think you want to do that, it'll be easier for people to explain why you actually don't.

avatar image oxidedivision · Feb 06, 2019 at 09:19 PM 0
Share

Thanks for your comments, guys. Can you please help me understand what is meant by 'internal initialization'? The way I see it, my Player object depends on a reference to the Conrtoller object (and vis versa), so they should each get this during the Awake function. I guess I'm wrong, but I dont understand how.

@Bonefire-boy, your suggestion would probably work great for this limited example, however I have many other classes that need to get a refrence to other classes - this would not be suitable for all.

I think what I'm trying to achieve is pretty basic; what would be the standardised way of achieving this?

Thanks

avatar image Ymrasu oxidedivision · Feb 06, 2019 at 09:27 PM 0
Share

Internal initialization in Awake meaning things only to that object, like grabbing components attached to the object itself. If you need initialization with other objects (such as child or parent objects) it should be done in Start.

avatar image oxidedivision Ymrasu · Feb 06, 2019 at 09:47 PM 0
Share

@Ymrasu, thanks that deffo helps! I guess I'm trying to treat the Awake function like a standard constructor, and thats really not what it is.

Anyways, gathering these dependencies during the Start method seems to give me a what I need, so I think thats the answer.

I've read other suggestions elsewhere (using singletons, using DI frameworks) which sound like they come with their own downside's. Simply getting the objects in the Start method seems to give me what I want.

Thanks all!

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by AbubakrKhan · Feb 07, 2019 at 01:13 AM

I have done this for you. Different methods to access script of parent object from child object vice versa. [Use of GetComponentsInChildren() and GetComponentInParent()]

3 Scripts each holding a method that I am accessing : GrandParent , Parent, Child attached to 3 Objects


  • GrandParentObject

  • --------------------------- ParentObject

  • ------------------------------------------------- ParentObject


This Script Shows multiple methods of doing the same thing for better understanding. There is another way of doing it by just making a public static instance of a class and then u can use that instance directly in other class without needing to create an object of that class. I can go in detail of this one in comments if required. Thanks if it answers what you are looking for please mark it as answered. Cheers!


GrandParent Class

 using UnityEngine;
 public class GrandParent : MonoBehaviour {

 //Method 1:  Accessing Child Script From GrandParent Script
 GameObject parentObject;
 GameObject childObject;
 Child child;
 Parent parent;

 //Method 2: Accessing Child Script From GrandParent Scrip

 public Transform[] childrenObjects;

 void Awake () {

     print("---------------- METHOD 1 -------------");

     parentObject = transform.Find("Parent").gameObject;
     childObject = transform.Find("Parent/Child").gameObject;
     parent = parentObject.GetComponent<Parent>();
     child = childObject.GetComponent<Child>();
     child.InChild();
     parent.InParent();

     print(" --------- Method 1 short to access child -------------");

     child = this.transform.Find("Parent/Child").gameObject.GetComponent<Child>();
     child.InChild();

     //METHOD 2
     print("----- Method 2 GetComponentsInChildren When you have Alot of childrens -----");

     childrenObjects = GetComponentsInChildren<Transform>();
     
     for(int i = 0; i < childrenObjects.Length; i++)
     {

        
         if (childrenObjects[i].name == "Child")
         {
             child = childrenObjects[i].GetComponent<Child>();
             child.InChild();
         }
         if (childrenObjects[i].name == "Parent")
         {
             parent = childrenObjects[i].GetComponent<Parent>();
             parent.InParent();
         }
     
     }
     print("----- METHOD 2 With FOREACH Loop ----");
     foreach(Transform children in childrenObjects)
     {
         if(children.Find("Child")){
             child = children.GetComponentInChildren<Child>();
             child.InChild();
         }
         if(children.Find("Parent")){
             parent = children.GetComponentInChildren<Parent>();
             parent.InParent();
         }
     }

 }

 public void InGrandParent()
 {
     print("InGrandParent Object");
 }    
 }



Child Class

 using UnityEngine;
 public class Child : MonoBehaviour {
 Transform GrandParentObject;
 GrandParent gp;
 Parent p;
 public void Start()
 {
     print("--------- METHOD 1: From Child T GRAND PARENT  ---------");
     GrandParentObject = transform.root;
     gp = GrandParentObject.GetComponent<GrandParent>();
     gp.InGrandParent();


     print("-----------METHOD 2:  From Child to Parents  ----------------");
     gp = GetComponentInParent<GrandParent>();
     gp.InGrandParent();
     p = GetComponentInParent<Parent>();
     p.InParent();
     

 }
 public void InChild()
 {
     Debug.Log("child component found");
 }
 }



Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

102 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Why do I get a context error when using GameObject.FindWithTag in Awake/Start function and GetComponent in a function? 1 Answer

get_enabled can only be called from the main thread. 1 Answer

C# accessing an array from a script in a different gameobject outside of the awake function 0 Answers

GetComponent(); in Awake cant be accessed in Update 1 Answer

Getcomponent returns null on ios 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges