Search Unity

Initializing objects that depend on other objects

Discussion in 'Getting Started' started by pigtwo, Sep 19, 2019.

  1. pigtwo

    pigtwo

    Joined:
    Jan 29, 2019
    Posts:
    4
    Hello all,

    I have a pretty simple question that I can't seem to phase in a way to google. So sorry if this has been asked before.

    My question mostly about the general structure of unity projects and how to handle the initialization of multiple objects that may depend on other objects.

    In my case I have an object(Let's call it object A) that contains a bunch of static information. It is just a standalone object with a script attached. That script has a hardcoded path to an XML file that it uses to fill in the data for its fields. It fills this data in in the Start() method.

    I have another object(object B) that has a script that wants to use some of the fields of the first object so that it can initialize itself.

    The problem is I can't ensure that object A initializes before object B. So if object B initializes before object A the fields of object A won't be filled out yet.

    I see a couple ways around this but they feel clunky and hard to maintain. First, you could have object A call the initialization method of object B once it finished initializing itself. These seems bad because there is not really a logical link between these two objects and if object B needs some parameters passed to it for initialization then object A has to know about those. Also if many objects need information from object A, object A would need to call all of there initialization methods.

    The other option I see is just to have a check in the Update() method of object B to see if object A is initialized yet. This seems inefficient because this will mean that object B will check if object A is initialized every frame for the rest of time even after object B is initialized.

    I imagine my structure here is the problem and I shouldn't have done it the way I did but I don't see an obvious better solution.

    What is the typical way this is done in Unity?

    Thank you!
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    You can, if you have object A initialize itself in Awake() instead of Start(). All the Awake() methods are guaranteed to run before any of the Start() methods.

    The other sensible way to do this sort of thing, in some cases, is for what's called "lazy initialization" — that is, object A knows whether it's initialized or not, and any accesses to its data go through methods or computed properties that first check to see if it's been initialized, and if not, does so on the spot.

    Then it doesn't matter when some other object asks for data; upon the first such request, all the data gets loaded.

    But for simple cases, just use Awake for early initializers, and use Start for anything else.
     
    pigtwo likes this.
  3. pigtwo

    pigtwo

    Joined:
    Jan 29, 2019
    Posts:
    4
    Thank you very much!

    Lazy initialization is exactly what I was looking for! Although I probably can get away with just using Awake and Start at first.
     
  4. pigtwo

    pigtwo

    Joined:
    Jan 29, 2019
    Posts:
    4
    One quick additional question:

    Is there any danger of implementing the lazy initialization via the getter/setter? Some googling shows there is a Lazy type that was made for this but I'd prefer to just do via the getter/setter.

    I did a quick test like this just to verify I understood it. Below is what I came up with and it seems to do what I need.
    Code (CSharp):
    1. public class LazyClass
    2. {
    3.     private Item GetThisItem;
    4.     public Item getThisItem
    5.     {
    6.         get
    7.         {
    8.             if(GetThisItem == null)
    9.             {
    10.                 init();
    11.                 return GetThisItem;
    12.             }
    13.             else
    14.             {
    15.                 return GetThisItem;
    16.             }
    17.         }  
    18.         set
    19.         {
    20.             GetThisItem = value;
    21.         }
    22.     }
    23.    
    24.     public LazyClass()
    25.     {
    26.         GetThisItem = null;  
    27.     }
    28.    
    29.     public Item init()
    30.     {
    31.         GetThisItem = new Item(1);
    32.     }
    33. }
    34.  
    35. public class Item
    36. {
    37.     public int num;
    38.    
    39.     public Item(int num)
    40.     {
    41.         this.num = num;
    42.     }
    43. }
     
    JoeStrout likes this.
  5. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Yes, I believe you've got the right idea.
     
    pigtwo likes this.