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:
- Create an array for your instantiated GameObjects with the length of the original characters array and is populated by the instantiated objects
- 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]);
}
}