Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Resolved passing information across scenes execute with delay

Discussion in 'Scripting' started by Daviiid, Feb 26, 2023.

  1. Daviiid

    Daviiid

    Joined:
    Oct 9, 2015
    Posts:
    50
    I have 2 scenes:
    Scene 1 you choose weapons...and what not
    Scene 2 is the game.

    I've made an object that has the weapons and stuff attached to it in the first scene. I've added a DontDestroyOnLoad(gameObject); command to it. So it goes to the next scene.
    I've also added a SceneManager.sceneLoaded += OnLevelFinishedLoading; event on it.

    My issue is that if I use this method I get a null reference error. It seems to me that the OnEnable(), Awake() and Start() functions haven't executed on all the objects that are in that scene yet.

    So I've added a 0.1f delay to the execution of the code.(I've used Invoke("blabla",0.1f), but not sure if I should use a coroutine to delay instead?)

    My question is when does Time start. Is it after the level is loaded? Or is it after all the OnEnable(), Awake() and Start() functions have executed. Because if it's before the initialization then a slower PC might need more than 0.1f delay. And I could get another null reference error.

    Or is there better way to do this?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    Make a GameManager that tracks all your state.

    Scene 1 contacts the GameManager to change state

    Scene 2 contacts the GameManager to read the state.

    ULTRA-simple static solution to a GameManager:

    https://forum.unity.com/threads/i-need-to-save-the-score-when-the-scene-resets.1168766/#post-7488068

    https://gist.github.com/kurtdekker/50faa0d78cd978375b2fe465d55b282b

    OR for a more-complex "lives as a MonoBehaviour or ScriptableObject" solution...

    Simple Singleton (UnitySingleton):

    Some super-simple Singleton examples to take and modify:

    Simple Unity3D Singleton (no predefined data):

    https://gist.github.com/kurtdekker/775bb97614047072f7004d6fb9ccce30

    Unity3D Singleton with a Prefab (or a ScriptableObject) used for predefined data:

    https://gist.github.com/kurtdekker/2f07be6f6a844cf82110fc42a774a625

    These are pure-code solutions, DO NOT put anything into any scene, just access it via .Instance!

    The above solutions can be modified to additively load a scene instead, BUT scenes do not load until end of frame, which means your static factory cannot return the instance that will be in the to-be-loaded scene. This is a minor limitation that is simple to work around.

    If it is a GameManager, when the game is over, make a function in that singleton that Destroys itself so the next time you access it you get a fresh one, something like:

    Code (csharp):
    1. public void DestroyThyself()
    2. {
    3.    Destroy(gameObject);
    4.    Instance = null;    // because destroy doesn't happen until end of frame
    5. }
    There are also lots of Youtube tutorials on the concepts involved in making a suitable GameManager, which obviously depends a lot on what your game might need.
     
  3. Daviiid

    Daviiid

    Joined:
    Oct 9, 2015
    Posts:
    50
    Thanks for the reply. These are just to carry things over from 1 scene to another. I already have them.
    The thing I was lacking was a way to start executing a script after all the other Start() scripts have finished. So I don't get a null reference error.

    I think I've managed to do it with a more reliable method, then my first try.
    I Still have the SceneManager.sceneLoaded += OnLevelFinishedLoading; event. Which fires of after each scene change. At that point I just Instantiate a temp gameobject that adds the player weapons and stuff in the Start() script.
    I've also changed the script execution order of that script to be a bit after the default execution. So it's executed always after all the other Start() scripts have been executed.