Forum begins after the advertisement:
[Part 7] Game Manager disappear after game load
Home › Forums › Video Game Tutorial Series › Creating a Metroidvania in Unity › [Part 7] Game Manager disappear after game load
- This topic has 7 replies, 3 voices, and was last updated 6 days, 4 hours ago by
Sean Ng.
-
AuthorPosts
-
July 2, 2026 at 12:41 am #19780::
My Game Manager just disappear from the button after i start the game. When i try to add it back in Play Mode, the death screen UI does not turn off, only the scene faded run
using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.SceneManagement; public class GameManager : MonoBehaviour { public string Transitionfrom; public Vector2 PlatformrespawnPoint; public Vector2 respawnAfterDeath; [SerializeField] LightSpot lightSpot; public GameObject Shade; public static GameManager Instance { get; private set; } private void Awake() { SaveData.saveinstance.Instantiate(); if (Instance != null && Instance != this) { Destroy(gameObject); } else { Instance = this; } if (PlayerController.Instance == null) { if (PlayerController.Instance.respawnMana) { SaveData.saveinstance.LoadShadeData(); if (SaveData.saveinstance.scenewithShade == UnityEngine.SceneManagement.SceneManager.GetActiveScene().name || SaveData.saveinstance.scenewithShade == "") { Instantiate(Shade, SaveData.saveinstance.shadePos, SaveData.saveinstance.shadeRotation); } } } SaveScene(); DontDestroyOnLoad(gameObject); lightSpot = FindObjectOfType<LightSpot>(); } public void SaveScene() { string currentSceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; SaveData.saveinstance.sceneNames.Add(currentSceneName); } public void respawnPlayer() { SaveData.saveinstance.LoadLightSpot(); if (SaveData.saveinstance.spotSceneName != null) { SceneManager.LoadScene(SaveData.saveinstance.spotSceneName); } if (SaveData.saveinstance.lightPos != null) { respawnAfterDeath = SaveData.saveinstance.lightPos; } else { respawnAfterDeath = PlatformrespawnPoint; } PlayerController.Instance.transform.position = respawnAfterDeath; StartCoroutine(UIManager.Instance.DeactivateDeathScreen()); PlayerController.Instance.Respawn(); } }Here is the Game manager script
July 2, 2026 at 9:52 pm #19781::I’ll have to look at your project more closely to figure this out, but you have a mistake here:
if (PlayerController.Instance == null)if (PlayerController.Instance != null) { if (PlayerController.Instance.respawnMana) { SaveData.saveinstance.LoadShadeData(); if (SaveData.saveinstance.scenewithShade == UnityEngine.SceneManagement.SceneManager.GetActiveScene().name || SaveData.saveinstance.scenewithShade == "") { Instantiate(Shade, SaveData.saveinstance.shadePos, SaveData.saveinstance.shadeRotation); } } }Also, at the start of
Awake(), add a return to prevent code from running if the GameObject is already destroyed.private void Awake() { SaveData.saveinstance.Instantiate(); if (Instance != null && Instance != this) { Destroy(gameObject); return; // stop executing on the object that's about to be destroyed } ...Let me know if this fixes things.
July 2, 2026 at 11:57 pm #19782::The problem with the Game Manager has been fixed, but when i press respawn button the shade disappear immediately and the player stuck in halfmana mode
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Shade : Enemy { [SerializeField] private float chaseRange; [SerializeField] private float stunDuration; float timer; public static Shade Instance; private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); } else { Instance = this; } SaveData.saveinstance.SaveShadeData(); } protected override void Start() { base.Start(); ChangeState(EnemyStates.Shade_Idle); } protected override void Update() { base.Update(); if (!PlayerController.Instance.pState.alive) { ChangeState(EnemyStates.Shade_Idle); } } protected override void UpdateEnemyStates() { float _dist = Vector2.Distance(transform.position, PlayerController.Instance.transform.position); switch (GetCurrentEnemyStates) { case EnemyStates.Shade_Idle: rb.velocity = new Vector2(0, 0); if (_dist < chaseRange) { ChangeState(EnemyStates.Shade_Chase); } break; case EnemyStates.Shade_Chase: rb.MovePosition(Vector2.MoveTowards(transform.position, PlayerController.Instance.transform.position, speed * Time.deltaTime)); FlipShade(); if (_dist > chaseRange) { ChangeState(EnemyStates.Shade_Idle); } break; case EnemyStates.Shade_Stun: timer += Time.deltaTime; if (timer > stunDuration) { ChangeState(EnemyStates.Shade_Chase); timer = 0; } break; case EnemyStates.Shade_Died: Death(Random.Range(5, 10)); break; } } protected override void Death(float _destroyTime) { rb.gravityScale = 1; base.Death(_destroyTime); } public override void EnemyHit(float _damageDone, Vector2 _hitDirection, float _hitForce) { base.EnemyHit(_damageDone, _hitDirection, _hitForce); if (health > 0) { ChangeState(EnemyStates.Shade_Stun); } else { ChangeState(EnemyStates.Shade_Died); } } protected override void ChangeCurrentAnim() { if (GetCurrentEnemyStates == EnemyStates.Shade_Idle) { anim.Play("idle"); } anim.SetBool("Walking", GetCurrentEnemyStates == EnemyStates.Shade_Chase); anim.SetBool("takeDamage", GetCurrentEnemyStates == EnemyStates.Shade_Stun); if (GetCurrentEnemyStates == EnemyStates.Shade_Died) { anim.SetTrigger("Death"); SaveData.saveinstance.SavePlayerData(); Destroy(gameObject, 0.5f); PlayerController.Instance.RestoreMana(); } } protected override void Attack() { PlayerController.Instance.TakeDamage(damage); } void FlipShade() { sr.flipX = PlayerController.Instance.transform.position.x < transform.position.x; } }Here is the Shade.cs
July 3, 2026 at 10:50 am #19783::Looking at the shade script alone I don’t see how it would cause a problem, but from what you describe it seems the shade never died but removed from scene which is why the player is stuck in half mana.
I need more information to know whats happening, when you click respawn did
SceneManager.LoadScene()run, if it did it will explain why the shade was removed and I need to look atGameManager.csandSaveData.cs.July 3, 2026 at 12:29 pm #19784::Here is the GameManager.cs
using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.SceneManagement; public class GameManager : MonoBehaviour { public string Transitionfrom; public Vector2 PlatformrespawnPoint; public Vector2 respawnAfterDeath; [SerializeField] LightSpot lightSpot; public GameObject Shade; public static GameManager Instance { get; private set; } private void Awake() { SaveData.saveinstance.Instantiate(); if (Instance != null && Instance != this) { Destroy(gameObject); return; } else { Instance = this; } if (PlayerController.Instance != null) { if (PlayerController.Instance.respawnMana) { SaveData.saveinstance.LoadShadeData(); if (SaveData.saveinstance.scenewithShade == UnityEngine.SceneManagement.SceneManager.GetActiveScene().name || SaveData.saveinstance.scenewithShade == "") { Instantiate(Shade, SaveData.saveinstance.shadePos, SaveData.saveinstance.shadeRotation); } } } SaveScene(); DontDestroyOnLoad(gameObject); lightSpot = FindObjectOfType<LightSpot>(); } public void SaveScene() { string currentSceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; SaveData.saveinstance.sceneNames.Add(currentSceneName); } public void respawnPlayer() { SaveData.saveinstance.LoadLightSpot(); if (SaveData.saveinstance.spotSceneName != null) { SceneManager.LoadScene(SaveData.saveinstance.spotSceneName); } if (SaveData.saveinstance.lightPos != null) { respawnAfterDeath = SaveData.saveinstance.lightPos; } else { respawnAfterDeath = PlatformrespawnPoint; } PlayerController.Instance.transform.position = respawnAfterDeath; StartCoroutine(UIManager.Instance.DeactivateDeathScreen()); PlayerController.Instance.Respawn(); } }And Here is the SaveData.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; using UnityEngine.SceneManagement; [System.Serializable] public struct SaveData { public static SaveData saveinstance; public HashSet<string> sceneNames; public string spotSceneName; public Vector2 lightPos; public int playerHealth; public float playerMana; public bool playerRespawnMana; public Vector2 playerPosition; public string lastScene; public Vector2 shadePos; public string scenewithShade; public Quaternion shadeRotation; public void Instantiate() { if (!File.Exists(Application.persistentDataPath + "/save.light.dat")) { BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.light.dat")); } if (!File.Exists(Application.persistentDataPath + "/save.player.dat")) { BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.player.dat")); } if (!File.Exists(Application.persistentDataPath + "/save.shade.dat")) { BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.shade.dat")); } if (sceneNames == null) { sceneNames = new HashSet<string>(); } } public void SavedLightSpot() { using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.light.dat"))) { writer.Write(spotSceneName); writer.Write(lightPos.x); writer.Write(lightPos.y); } } public void LoadLightSpot() { if (File.Exists(Application.persistentDataPath + "/save.light.dat")) { using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.light.dat"))) { spotSceneName = reader.ReadString(); lightPos.x = reader.ReadSingle(); lightPos.y = reader.ReadSingle(); } } } public void SavePlayerData() { using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.player.dat"))) { playerHealth = PlayerController.Instance.Health; writer.Write(playerHealth); playerMana = PlayerController.Instance.Mana; writer.Write(playerMana); playerRespawnMana = PlayerController.Instance.respawnMana; writer.Write(playerRespawnMana); playerPosition = PlayerController.Instance.transform.position; writer.Write(playerPosition.x); writer.Write(playerPosition.y); lastScene = SceneManager.GetActiveScene().name; writer.Write(lastScene); } } public void LoadPlayerData() { if (File.Exists(Application.persistentDataPath + "/save.player.dat")) { using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.player.dat"))) { playerHealth = reader.ReadInt32(); playerMana = reader.ReadSingle(); playerRespawnMana = reader.ReadBoolean(); playerPosition.x = reader.ReadSingle(); playerPosition.y = reader.ReadSingle(); lastScene = reader.ReadString(); SceneManager.LoadScene(lastScene); PlayerController.Instance.transform.position = playerPosition; PlayerController.Instance.Health = playerHealth; PlayerController.Instance.Mana = playerMana; PlayerController.Instance.respawnMana = playerRespawnMana; } } else { Debug.Log("No save file found for player data."); PlayerController.Instance.Health = PlayerController.Instance.maxHealth; PlayerController.Instance.Mana = 0.5f; PlayerController.Instance.respawnMana = false; } } public void SaveShadeData() { using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.shade.dat"))) { scenewithShade = SceneManager.GetActiveScene().name; shadePos = Shade.Instance.transform.position; shadeRotation = Shade.Instance.transform.rotation; writer.Write(scenewithShade); writer.Write(shadePos.x); writer.Write(shadePos.y); writer.Write(shadeRotation.x); writer.Write(shadeRotation.y); writer.Write(shadeRotation.z); writer.Write(shadeRotation.w); } } public void LoadShadeData() { if (File.Exists(Application.persistentDataPath + "/save.shade.data")) { using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.shade.dat"))) { scenewithShade = reader.ReadString(); shadePos.x = reader.ReadSingle(); shadePos.y = reader.ReadSingle(); float shadeRotationx = reader.ReadSingle(); float shadeRotationy = reader.ReadSingle(); float shadeRotationz = reader.ReadSingle(); float shadeRotationw = reader.ReadSingle(); shadeRotation = new Quaternion(shadeRotationx, shadeRotationy, shadeRotationz, shadeRotationw); } } else { Debug.Log("No save file found for shade data."); } } }July 3, 2026 at 10:38 pm #19785::The problem is found in your
GameManager.cs, when you respawn you will load scene even if it is the same it will refresh the scene, this causes your shade to dissapear as it is not part of the original scene, as yourGameManager.csAwake()function is only called once at the start when the game begins the shade data is never loaded.To fix this We’ll move it down and create a new function that load shade data everytime the scene change.
using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.SceneManagement; public class GameManager : MonoBehaviour { public string Transitionfrom; public Vector2 PlatformrespawnPoint; public Vector2 respawnAfterDeath; [SerializeField] LightSpot lightSpot; public GameObject Shade; public static GameManager Instance { get; private set; } private void Awake() { SaveData.saveinstance.Instantiate(); if (Instance != null && Instance != this) { Destroy(gameObject); return; } else { Instance = this; } if (PlayerController.Instance != null) { if (PlayerController.Instance.respawnMana) { SaveData.saveinstance.LoadShadeData(); if (SaveData.saveinstance.scenewithShade == UnityEngine.SceneManagement.SceneManager.GetActiveScene().name || SaveData.saveinstance.scenewithShade == "") { Instantiate(Shade, SaveData.saveinstance.shadePos, SaveData.saveinstance.shadeRotation); } } } SaveScene(); DontDestroyOnLoad(gameObject); lightSpot = FindObjectOfType<LightSpot>(); } public void SaveScene() { string currentSceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; SaveData.saveinstance.sceneNames.Add(currentSceneName); } public void respawnPlayer() { SaveData.saveinstance.LoadLightSpot(); if (SaveData.saveinstance.spotSceneName != null) { SceneManager.LoadScene(SaveData.saveinstance.spotSceneName); } if (SaveData.saveinstance.lightPos != null) { respawnAfterDeath = SaveData.saveinstance.lightPos; } else { respawnAfterDeath = PlatformrespawnPoint; } PlayerController.Instance.transform.position = respawnAfterDeath; StartCoroutine(UIManager.Instance.DeactivateDeathScreen()); PlayerController.Instance.Respawn(); } private void OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded; } private void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (PlayerController.Instance != null) { if (PlayerController.Instance.respawnMana) { SaveData.saveinstance.LoadShadeData(); if (SaveData.saveinstance.scenewithShade == UnityEngine.SceneManagement.SceneManager.GetActiveScene().name || SaveData.saveinstance.scenewithShade == "") { Instantiate(Shade, SaveData.saveinstance.shadePos, SaveData.saveinstance.shadeRotation); } } } SaveScene(); DontDestroyOnLoad(gameObject); lightSpot = FindObjectOfType<LightSpot>(); } }July 4, 2026 at 12:28 am #19786::The Shade is now display but when i kill it and then restart the game, the player is still at halfmana state but the shade is gone
July 4, 2026 at 6:11 pm #19787::when you kill the shade does your mana restore? If the only problem is when restart the player go back to half mana, to fix it you just need to rearrange the code at your
ChangeCurrentAnim()ofShade.csprotected override void ChangeCurrentAnim() { if (GetCurrentEnemyStates == EnemyStates.Shade_Idle) { anim.Play("idle"); } anim.SetBool("Walking", GetCurrentEnemyStates == EnemyStates.Shade_Chase); anim.SetBool("takeDamage", GetCurrentEnemyStates == EnemyStates.Shade_Stun); if (GetCurrentEnemyStates == EnemyStates.Shade_Died) { anim.SetTrigger("Death"); PlayerController.Instance.RestoreMana(); SaveData.saveinstance.SavePlayerData(); Destroy(gameObject, 0.5f); } }You want the
RestoreMana()to go first beforeSavePlayerData()otherwise it won’t save the player mana state.has upvoted this post. -
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: