Search Unity

DontDestroyOnLoad resets my values

Discussion in 'Scripting' started by Karwoch, Oct 6, 2015.

  1. Karwoch

    Karwoch

    Joined:
    Sep 16, 2014
    Posts:
    111
    I did a simple test - here is my code:

    Code (CSharp):
    1.  
    2. public class test : MonoBehaviour {
    3.  
    4.     bool testedValue;
    5.  
    6.  
    7.     void Awake () {
    8.         Debug.Log("tested value on load:" + testedValue);
    9.         DontDestroyOnLoad(this.gameObject);
    10.     }
    11.      // Use this for initialization
    12.     void Start () {
    13.         testedValue = true;
    14.     }
    15.    
    16.     void Restart () {
    17.         Application.LoadLevel(Application.loadedLevel);
    18.     }
    19. }
    And always after restarting level my bool value is false. From my understanding, DontDestroyOnLoad shouldnt reset my value, so why it is happening?
     
  2. Craig8726

    Craig8726

    Joined:
    Jul 5, 2013
    Posts:
    79
    thats weird. Is the gameobject that Test is attached to in the scene. if so its probably loading it again with the scene so you end up with two. That may cause some weird behaviour. Check your scene for multiple copies of the game object when running restart function.
     
  3. Karwoch

    Karwoch

    Joined:
    Sep 16, 2014
    Posts:
    111
    Thank You for answer!

    So I have added some code to make sure it is single, and I have unfortunatly still exacly same results...

    Code (CSharp):
    1.    
    2. bool testedValue;
    3.  
    4.  
    5.     public static test tested;
    6.  
    7.     void Awake (){
    8.         Debug.Log("tested value on load:" + testedValue);
    9.  
    10.  
    11.         if (tested == null)
    12.         {
    13.             DontDestroyOnLoad(gameObject);
    14.             tested = this;
    15.         }
    16.         else if (tested != this)
    17.         {
    18.             Destroy(gameObject);
    19.         }
    20.     }
    21.  
    22.  
    23.      // Use this for initialization
    24.     void Start () {
    25.         testedValue = true;
    26.     }
    27.  
    28.     void Restart () {
    29.         Application.LoadLevel(Application.loadedLevel);
    30.     }
     
  4. Karwoch

    Karwoch

    Joined:
    Sep 16, 2014
    Posts:
    111
    I just created new project, with only one gameobject, canvas and restart button. On gameobject I`ve attached this script, assigned button to restart function, and tested it - still this GO is set to false on restart...

    I have managed to workaround by saveing bool in file, but it isn`t very good in futher perspective, any idea what can be wrong?
     
  5. Craig8726

    Craig8726

    Joined:
    Jul 5, 2013
    Posts:
    79
    try loading a different empty scene and see if you still get the bool resetting problem.
     
  6. Craig8726

    Craig8726

    Joined:
    Jul 5, 2013
    Posts:
    79
    the bool is private so are you using the debug in awake for verificaiton. if so when you reload the scene the new gameobject that was loaded with the scene is debugging it as false because it runs before it is set to true in start.
    make the bool public and check it in the inspector.
     
    Karwoch likes this.
  7. Karwoch

    Karwoch

    Joined:
    Sep 16, 2014
    Posts:
    111
    Thank You! With this idea I managed to solve this mistery... Althought answer is a little different - Awake is called only on creation, so putting debug in awake was called only for new instances which always had false value. So even when there is single instance check - debug was before this check, so it displayed value for instantly after destroyed GO. And everything in start in right GO wasn`t runned because there is no start in loading level with dontdestroyonload.

    Now I have next dillema because of this behavior - I have to use OnLevelWasLoaded - but it is called before Awake(!), so I always get two answers - one for GO which is from previous scene, and second which is created in this scene, but isn`t yet destroyed. Any if statement I will use, still be affected by this zombie GO which just won`t die in time ;) Maybe You have any sugestions?

    I have one workaround - to start coroutine in onlevelwasloade with one yield return null, but it is little dangerous as I use it already for other things which I couldn`t put in start, because it was too early for other things in other start`s GO (as I had read about start sequence, You can`t be ever sure which GO will run first code in this section)
     
    Last edited: Oct 7, 2015
  8. Craig8726

    Craig8726

    Joined:
    Jul 5, 2013
    Posts:
    79
    instead of having it in the scene by default use a script to instantiate a prefab of the gameobject on start up of the scene if no other gameobjects of the same exist. example using a tag to look.
    Code (CSharp):
    1. void Start()
    2.     {
    3.         if(!GameObject.FindGameObjectWithTag("This tag"))
    4.         {
    5.             Instantiate(prefab);
    6.         }
    7.     }
    that way it will only exist if another gameobject with the same tag doesnt already exist.
     
  9. Karwoch

    Karwoch

    Joined:
    Sep 16, 2014
    Posts:
    111
    Nice thought, but when there are two of this objects, both won`t do anything (in case of putting this code in onlevelwasloaded), and on start will work only on new one, second won`t call this method as it isn`t created in new scene (so I need to use OnLevelWasLoaded). Anyway, now I will figure something out, many thanks!