The neatest way to do this is probably with an event. Content that needs to initialize after the map's physics are ready can subscribe to the event.
Using a generator method like the one below, this subscription can be as simple as:
void Start() {
MapGenerator.DeferUntilPhysicsReady(InitializeAfterPhysics);
}
void InitializeAfterPhysics() {
// Do the thing.
}
Here's a sketch of a generator script that can handle this deferred initialization:
public class MapGenerator : MonoBehaviour
{
static MapGenerator _instance;
public static MapGenerator instance { get {
if (_instance == null)
_instance = FindObjectOfType<MapGenerator>();
return _instance;
} }
public static void DeferUntilPhysicsReady(System.Action callback) {
var generator = instance;
if (generator == null) {
Debug.LogError("Trying to defer in scene with no Map Generator.");
return;
}
if(generator._isPhysicsReady) {
// Handle late-spawning scripts that can safely initialize now.
callback();
} else {
// Otherwise, wait until physics is ready, then call it.
generator.OnPhysicsReady += callback;
}
}
public event System.Action OnPhysicsReady;
bool _isPhysicsReady;
IEnumerator Start()
{
GenerateMap();
// Wait until just before the next physics step.
yield return new WaitForFixedUpdate();
// Let physics step at least once, then resume after Update().
yield return null;
_isPhysicsReady = true;
// Physics are all up to date:
// ready to call our deferred initialization methods.
if (OnPhysicsReady != null)
OnPhysicsReady();
}
void GenerateMap() {
// Do the thing.
}
}
You can even offload this subscription logic to a separate standalone component that wakes the rest. Just spawn you object with the sensitive scripts initially disabled, and use a script like this to wake them and start ticking their Start / Updates on demand:
public class WakeAfterMapReady : MonoBehaviour {
public Behaviour[] disabledBehaviours;
void Start() {
MapGenerator.DeferUntilPhysicsReady(InitializeAfterPhysics);
}
void InitializeAfterPhysics() {
foreach (var behaviour in disabledBehaviours)
behaviour.enabled = true;
}
}