Passing "Initial Condition" variables from a GameManager object to prefabs?

I’m running into some odd Hierarchial problems.

I’ve made a levelManager empty object that instantiates all of my level’s prefabs. But each prefab has certain characteristics (Size, quantity, etc) that is innate to each of them respectively. For instance:

LevelManager instantiates a Floor prefab
Floor instantiates some “Tile” prefabs

public tileSize is a variable unique to “Tile”
public numTiles is a constant variable unique to “Floor”

I want to be able to pass these variables to “Floor” and “Tile” from the level manager, so I can change all of the variables of my level without having to altering each prefab - that way I only have to open up one script to change my level how I like.

So I create a public “LevelManager_Prefab” variable of type “LevelManager” in each one of my prefab scripts. and point each variable in each script to my main levelManager prefab.

And in my Floor/Tile scripts, I access the needed variables via LevelManager_Prefab.tileSize, or LevelManager_Prefab.numTiles

Here’s my problem: It’s as if my prefabs aren’t properly “Seeing” the variables being passed to them from my levelmanager prefab - sometimes they seem to grab the needed variable reliably, but it’s inconsistent. I think there’s something I’m not understanding regarding when variables are initialized. I have a hunch that some of my prefabs are reaching for the variable they need before it exists in the level manager. But I can’t figure out the exact problem.

Has anyone run into this? Is there some hard/fast rule that I should be following? Am I doing something glaringly wrong?

You could try using OnLevelWasLoaded to initialize. Something I do is create my managers in an init scene and set them as DontDestroyOnLoad in the awake, and then change scenes in the start. I use a public nextScene string and change it for the level I’m working on in the editor.

It could be an issue with script execution order. Dependent scripts might be trying to access the level manager before it’s initialized. Can you try changing the script execution order so that your level manager script runs first?

Oh I haven’t tried that! I’ve been changing their execution order with StartCoroutine(“…”) and yield WaitForSeonds(“#”)

Nope, doesn’t work.

  1. All objects can grab variables directly from the level manager, but they can’t grab variables from each other on Start, despite my ordering them properly in the script order manager.

This works on startup:
myFloor grabs “numTiles” from myLevelManager
myTile grabs “tileSize” from myLevelManager

This fails however:
myFloor Fails to grab “tileSize” from myTile

Or think of it like this (The bolded part fails):
MyLevelManager → "numTiles" → myFloor
MyLevelManager → "tileSize" → myTile → "tileSize" → myFloor

In the script order manager, I sort LevelManager first, then myTile, then myFloor. Yet they don’t seem to be grabbing variables in that order.

  1. My prefabs are only grabbing variables from the LevelManager if those variables are given a value inside of the inspector and if the levelManager has not yet been placed in the hierarchy. If I want to change a variable the other prefabs will grab from levelManager, like levelManager.numTiles, I have to delete the instance of levelManager, change “numTiles” variable in the PREFAB, and then add it back to the hierarchy. I can’t just change the instance variable value. And assigning values in the levelManager SCRIPT does nothing. I have to give values to the inspector outside of the hierarchy

Use Awake to set variables, use Start to grab variables. All Awake run before any Start.

How about adding an init script / function to your prefabs and calling that function after creating them with your manager? You can even pass a reference to a level transform they’ll all be parented to so they can cheaply find each other by iterating over the parent children. A level parent will also make your hierarchy clean :slight_smile:

I’ve found that public variables get overridden by the editor and it can get confusing. If don’t need publics, use privates and gets and sets.

It took me a while to realize this when I first used unity, and it really slowed me down lol. At least it gives the Awake function a purpose on simpler data components.