Search Unity

How to use SceneManager.onSceneLoaded ?

Discussion in 'Scripting' started by clawd31, Apr 22, 2016.

  1. clawd31

    clawd31

    Joined:
    Aug 5, 2013
    Posts:
    26
    I've upgraded to Unity 5.4b15 and now i have a lot of warning saying that OnLevelWasLoaded is deprecated.
    I've tried to find SceneManager.onSceneLoaded on the 5.4 doc but it's not complete and there is no script exemple.
    Anyone know how SceneManager.onSceneLoaded works ?
     
    Last edited: Apr 22, 2016
    Divergent916 and jwinn like this.
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    It's an event. Append a delegate to it to receive callbacks.

    Knowing Unity, it's probably of type System.Action (you can righclick it in Visual Studio or MonoDevelop and click goto definition to see). So it'd be something along the lines of:

    Code (csharp):
    1.  
    2. void Start()
    3. {
    4.     SceneManager.sceneLoaded += OnSceneLoaded;
    5. }
    6.  
    7. void OnSceneLoaded()
    8. {
    9.     //do stuff
    10. }
    11.  
     
    St0wy, Berty_Bert and Divergent916 like this.
  3. Goodeddie

    Goodeddie

    Joined:
    Aug 3, 2016
    Posts:
    79
    Actually you have to pass in parameters into the delegate. I believe it has a Scene and a SceneMode
     
    CompFreakAlpha and Divergent916 like this.
  4. jhuynh_

    jhuynh_

    Joined:
    Sep 2, 2016
    Posts:
    7
    this worked for me to do something every time a new scene loaded

    void Update () {
    SceneManager.sceneLoaded += OnSceneLoaded;
    }

    void OnSceneLoaded (Scene scene, LoadSceneMode mode) {
    //do stuff
    }
     
    sawnch, n2oukdnb and Divergent916 like this.
  5. catfink

    catfink

    Joined:
    May 23, 2015
    Posts:
    176
    This doesn't work for me because the timing of the event that gets fired for SceneManager.sceneLoaded is different to that of OnLevelWasLoaded. In my case the scene I just loaded has definitely not finished loading when this new call back is called and I get null reference exceptions when I try to access object that should be in the scene but aren't (yet). We have a discussion thread on this here ...

    http://forum.unity3d.com/threads/important-function-deprecated-what-is-the-new-alternative.424746/

    Unity are looking at it but we need others to add their voices to the discussion to get it noticed and fixed.
     
    pako and Divergent916 like this.
  6. Jo8bitVR

    Jo8bitVR

    Joined:
    Aug 6, 2017
    Posts:
    1
    I used the advice above (thank you everyone!) but still had to play around with the SceneManagement to get exactly what I wanted. Below I have posted how I changed my OnLevelWasLoaded() to OnSceneLoaded(). Maybe it will help someone else out!

    This is what I had:
    upload_2017-8-6_15-31-14.png

    And this is what I changed it to:
    upload_2017-8-6_15-29-6.png
     
    Divergent916 likes this.
  7. Divergent916

    Divergent916

    Joined:
    Nov 17, 2018
    Posts:
    4
    Thanks everyone who helped on this thread! I've been trying to find this solution for hours now!
     
  8. aklgupta

    aklgupta

    Joined:
    Jun 9, 2014
    Posts:
    29
    Just an advice. Don't add the delegate in Update like that, or it will try to add it multiple times, however, adding just once is more than enough.
     
  9. msibrava

    msibrava

    Joined:
    Mar 18, 2019
    Posts:
    7
    I ran into the same problem. I got a null reference exception because public text fields defined in the editor were not yet available when OnSceneLoaded() was calling a method in the script.

    I, instead, had the Start method from the script with the text fields test if the original object was in the scene, and then run what I was trying to run in OnSceneLoaded from the Start method. e.g.:

    Code (CSharp):
    1. public class Messenger : MonoBehaviour {
    2.  
    3.     public int selectedID;
    4.  
    5.     public void Start(){
    6.         DontDestroyOnLoad(this);
    7.     }
    8.  
    9.     public void DoSomething(){
    10.             LoadedScript.ShowID(selectedID);
    11.             DestroyObject(gameObject);
    12.     }
    13. }
    14.  
    And on the newly loaded scene there's an object with the script:

    Code (CSharp):
    1. public class LoadedScript : MonoBehaviour {
    2.  
    3. private Text[] idText;
    4.  
    5.     void Start () {
    6.         if (GameObject.Find("Messenger")){
    7.             Messenger messenger = GameObject.FindObjectOfType<Messenger>();
    8.             messenger.DoSomething();
    9.         }
    10. }
    11.  
    12.     ShowID(int selectedID){
    13.         idText.text = selectedID;
    14.     }
    15.  
    16. }