I have a DontDestroyOnLoad() object that needs to grab other objects when a scene loads. For example, it’s used to apply persistent attributes to the player character between scenes. However, I’m having trouble finding out which initialization methods fire when a new scene is loaded. The OnEnable()/OnSceneLoaded() methods seem to be the right place to go, but I can’t find when exactly these methods trigger so as to be sure that the player object has been created and is ready to be grabbed and modified.
I agree with @Addie in most cases… however, in my own projects I’ve found that doing async-loading, or instantiation on scene-load can mess with getting those objects. The way I used to get around that was to create an object, we’ll call it FullSceneLoadObj, that calls a GameManager function in update, then destroys itself.
Doing so allowed me to instantiate objects at scene-load, then grab/assign those objects to ref’s that needed them before starting the scenes first-run functionality.
@ArcaneTheWoof use the SceneManager.sceneLoaded event. The Player component in my example is attached to a gameObject in another scene, The Start method first places the manager in to the DonDestroyOnLoad first then loads the scene that the player is in.
using UnityEngine;
using UnityEngine.SceneManagement;
public class SomeManager : MonoBehaviour
{
//Start comes third
private void Start()
{
DontDestroyOnLoad(this);
SceneManager.LoadScene(1);
Debug.Log("Start");
}
//OnEnable comes first
private void OnEnable()
{
SceneManager.sceneLoaded += SceneManager_sceneLoaded;
Debug.Log("OnEnable");
}
//OnDisable last.
private void OnDisable()
{
SceneManager.sceneLoaded -= SceneManager_sceneLoaded;
Debug.Log("OnDisable");
}
//SceneLoad comes second.
private void SceneManager_sceneLoaded(Scene scene, LoadSceneMode mode)
{
if(scene.isLoaded)
{
Player player = FindObjectOfType<Player>();
if(player)
{
player.health = 100;
Debug.Log("Set Player Health");
}
Debug.Log("Scene Loaded");
}
}
}