Search Unity

On scene change event for DontDestroyOnLoad object?

Discussion in 'Scripting' started by Emolk, Jan 23, 2020.

  1. Emolk

    Emolk

    Joined:
    Feb 11, 2014
    Posts:
    241
    Hi. I have a script that manages other scripts for my Player object.

    The Player is DontDestroyOnLoad and i can't figure out how to call a function on any scene change.

    My code below:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine.SceneManagement;
    4. using UnityEngine;
    5.  
    6. public class ScriptSceneManager : MonoBehaviour
    7. {
    8.     private PlayerMovement movement;
    9.     private PlayerBlock blockPlacing;
    10.     private Attacks attacking;
    11.     private GhostBlockManager ghostBlock;
    12.     private PlayerHotBar hotBar;
    13.  
    14.     void Awake(){
    15.  
    16.         movement = GetComponent<PlayerMovement>();
    17.         blockPlacing = GetComponent<PlayerBlock>();
    18.         attacking = GetComponent<Attacks>();
    19.         ghostBlock = GetComponent<GhostBlockManager>();
    20.         hotBar = GetComponent<PlayerHotBar>();
    21.         DontDestroyOnLoad(gameObject);
    22.     }
    23.  
    24.     void Start(){
    25.         SceneManager.sceneLoaded += OnSceneLoaded;
    26.     }
    27.  
    28.     void EnableFunctions(){
    29.         movement.enabled = true;
    30.         movement.reFindReferences();
    31.         blockPlacing.enabled = true;
    32.         blockPlacing.reFindReferences();
    33.         attacking.enabled = true;
    34.         hotBar.enabled = true;
    35.         ghostBlock.enabled = true;
    36.     }
    37.  
    38.     public void DisableFunctions(){
    39.         blockPlacing.enabled = false;
    40.         attacking.enabled = false;
    41.         ghostBlock.enabled = false;
    42.         hotBar.enabled = false;
    43.     }
    44.  
    45.  
    46.  
    47.     void OnEnable()
    48.     {
    49.         SceneManager.sceneLoaded += OnSceneLoaded;
    50.         print("Scene has loaded");
    51.     }
    52.  
    53.     void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    54.     {
    55.  
    56.         print("Scene on scene");
    57.  
    58.         if (scene.name != "Testing" && scene.name != "Battle"){
    59.             DisableFunctions();
    60.         }
    61.  
    62.         else if(scene.name == "Battle"){
    63.             print("is battle");
    64.             EnableFunctions();
    65.             Invoke("SetBattleSpawnPos", 0.2f);
    66.             SetBattleSpawnPos();
    67.         }
    68.         else if(scene.name == "Testing"){
    69.             EnableFunctions();
    70.         }
    71.     }
    72.  
    73.     private void SetBattleSpawnPos(){
    74.  
    75.         LevelGenerator gen = LevelGenerator.instance;
    76.  
    77.         int xSpawnPos = gen.surfacemaxX/2;
    78.         Vector2 spawnPos = gen.getSurfacePos(xSpawnPos);
    79.         spawnPos.y += 1;
    80.         transform.position = spawnPos;
    81.     }
    82. }
    83.  
    When changing scenes, OnSceneLoaded is never called. OnEnabled is only called once (when the object is created). How do i trigger OnSceneLoaded when a scene is loaded when my object has DontDestroyOnLoad? I want to be able to disabled and enable different functions based on which scene is loaded. Thanks.
     
  2. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,261
    Order of operations: OnEnable -> Awake -> Start. They will only be called once, even when a new scene is loaded for objects with DontDestroyOnLoad. OnEnable will be called if you disable and re enable the object after the object is first enabled on creation.

    I use SceneManager.sceneLoaded += OnSceneLoaded; all the time in Awake or OnEnable and it works fine. I usually have it on a script that is run before everything else(script execution order.)

    It should work. Make sure its only set in OnEnable or Awake and try setting the script execution order of that script before the default time. I stick all of my Manager scripts before default time to ensure that they are loaded and ran before everything else.
     
    Switch_Z, abtlb76, Aca and 1 other person like this.
  3. Emolk

    Emolk

    Joined:
    Feb 11, 2014
    Posts:
    241
    Sorry if i wasn't clear, I need a function that is called on EVERY scene load, not just once.

    IE. whenever a scene is loaded, i want the script to do something based on which scene is loaded.
     
  4. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,261
    That's how it works. Once you register the event it will trigger on EVERY scene load. If you tried my suggestion and it still doesn't work then you found a bug.
     
    Fressbrett likes this.