Home > other >  Unity GameObject being deleted after using DontDestroyOnLoad
Unity GameObject being deleted after using DontDestroyOnLoad

Time:07-23

I am trying to preserve my character during scene changes using DontDestroyOnLoad(), but the character is being destroyed between the menu scene and the actual game even thought I have said DontDestroyOnLoad(gameObject).

Here is a picture of the Hierarchy and the Game Manager.

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour
{   
    public static GameManager instance;

    [SerializeField]
    private GameObject[] characters;

    private int _charIndex;
    public int CharIndex
    {
        get{ return _charIndex; }
        set{ _charIndex = value; }
    }

    void Awake(){
    //For the GameManager
    DontDestroyOnLoad(gameObject);
    
    //For the Characters
    for(int i = 0; i < characters.Length; i  ){
        DontDestroyOnLoad(characters[i]);
    }
}

    private void OnEnable()
    {
        SceneManager.sceneLoaded  = OnLevelFinishedLoading;
    }

    private void OnDisable()
    {
        SceneManager.sceneLoaded -= OnLevelFinishedLoading;
    }


    void OnLevelFinishedLoading(Scene scene, LoadSceneMode mode)
    {
        if (scene.name == "Gameplay")
        {
            Instantiate(characters[CharIndex]);
        }
    }
} // class

I have tried

    void Awake(){
    //For the GameManager
    DontDestroyOnLoad(gameObject);
    
    //For the Characters
    for(int i = 0; i < characters.Length; i  ){
        DontDestroyOnLoad(characters[i]);
    }

Instead of

if (instance == null)
   {
       instance =this;
       DontDestroyOnLoad(gameObject);
   }
else{
     Destroy(gameObject);
}

With the first one, the Gameplay wouldn't load and with the second one the scene would load but the characters get destroyed on load.

CodePudding user response:

DontDestroyOnLoad only works for root GameObjects or components on root GameObjects. You are trying to not destroy an array of gameobjects which I am not sure can be done unless you have the gameobjects in the Hierarchy as a root object and the gamemanager script attached to it.

CodePudding user response:

thanks for the response ! I didn't quite understand that last part of the gameobjects in the Hierarchy as a root object and the gamemanager script attached to it. Try this link to get to a screenshot of the Hierarchy. [1]: https://i.stack.imgur.com/GlmBF.png Thanks

CodePudding user response:

Edit

I completely missed this and assumed it was an issue with running DontDestroyOnLoad, but your problem is that calling Instantiate clones the object, so when you call DontDestroyOnLoad for your characters, you are calling it on Prefab Gameobjects which are not in the scene.

Solution:

  1. Create an array for your instantiated GameObjects with the length of the original characters array and is populated by the instantiated objects
  2. Call DontDestroyOnLoad() on THESE objects
private GameObject[] instantiatedCharacters;

...

void Awake(){
    //For the GameManager
    DontDestroyOnLoad(gameObject);
    
    //Create array with correct length. This is not strictly necessary, but will be needed if you want to destroy the objects from here.
    //This might need to go in Start()
    instantiatedCharacters = new GameObject[characters.length];
}

...


void OnLevelFinishedLoading(Scene scene, LoadSceneMode mode){
    if (scene.name == "Gameplay"){
        //
        instantiatedCharacters[CharIndex] = Instantiate(characters[CharIndex]);

        //Dont Destroy the newly created objects
        DontDestroyOnLoad(instantiatedCharacters[CharIndex]);
    }
}

Original Answer:

Instance is uninitialized and will always be null on load. You need instance = this; outside of the if statement in Awake()

Each time Awake() executes, you are calling Destroy(gameObject);

Edit: Because the picture shows that the GameManager class is on a separate objects and you are trying to preserve the characters, you need to call DontDestroyOnLoad for each one.

void Awake(){
    //For the GameManager
    DontDestroyOnLoad(gameObject);
    
    //For the Characters
    for(int i = 0; i < characters.length; i  ){
        DontDestroyOnLoad(characters[i]);
    }
}

  • Related