- Home /
When an object is DontDestroyOnLoad(), where can I put script that will run at the start of a new scene?
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.
Where should I put such initialization scripts?
Answer by GamitusLabs · Dec 12, 2018 at 05:39 PM
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.
Just tested this, and it worked perfectly, thank you! I agree that it's a bit of a workaround, but it also seems like it would be more consistent and intuitive and easy to keep track of, as well as being very useful for having different instructions for each individual scene.
Answer by Addie · Dec 12, 2018 at 05:23 PM
@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");
         }
     }
 }
It took me a bit to figure out what you were getting at because your initialization methods were out of chronological order, which was a bit confusing, but I think I got it, thanks!
So now I need to know: 1) Does the manager's Start() method fire on every scene load, or just when it's first instantiated? 2) Where does the _sceneLoaded() $$anonymous$$ethod here fire in relation to the other objects in the scene? Which methods will the player character have executed when _sceneLoaded() goes off?
Your answer
 
 
             Follow this Question
Related Questions
Multiple Cars not working 1 Answer
How can i use any imported model(for example Crysis Nanosuit) instead of mecanim rigged model? 0 Answers
RigidBody.It doesn't give speed to my gameObject 3 Answers
Custom Input Manager Menu Reset Keybinds 0 Answers
How do you put a List under an Array item (Hard time explaining) 1 Answer
 koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                