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.
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.
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.
public class LazyClass
{
private Item GetThisItem;
public Item getThisItem
{
get
{
if(GetThisItem == null)
{
init();
return GetThisItem;
}
else
{
return GetThisItem;
}
}
set
{
GetThisItem = value;
}
}
public LazyClass()
{
GetThisItem = null;
}
public Item init()
{
GetThisItem = new Item(1);
}
}
public class Item
{
public int num;
public Item(int num)
{
this.num = num;
}
}