Unity重启游戏时DontDestroyOnLoad场景玩家消失报错求助
问题描述
我正在开发一款名为Gravity Shifter的Unity游戏,重启游戏时,来自DontDestroyOnLoad场景的玩家对象消失,导致游戏报错并终止运行。游戏运行流程:GameManager从主菜单场景启动,点击开始按钮后进入Level1场景进行游戏。
PlayerManager.cs
using UnityEngine; public class PlayerManager : MonoBehaviour { public static PlayerManager instance; public static PlayerManager Instance { get { return instance; } } public GameObject player; public Vector3 startingPosition; // starting position when game restarts or starts private void Awake() { // Singleton yapısı if (instance == null) { instance = this; DontDestroyOnLoad(gameObject); // PlayerManager, sahne geçişlerinde yok edilmez } else { Destroy(gameObject); // Aynı PlayerManager birden fazla sahnede varsa, yalnızca biri kalır. } } // bu playeri yeniden baslatir (restart veya level sceneleri gecisleri icin) public void RestartPlayer() { if (player != null) { Destroy(player); // Eski player'ı sil } // Yeni player'ı oluştur ve başlat Instantiate(player, startingPosition, Quaternion.identity); } // Oyuncuyu Don't Destroy'dan çıkar ve sil (main menuye donerken cikartilir) public void RemovePlayerFromDontDestroy() { Destroy(gameObject); } }
GameManager.cs
using UnityEngine; using UnityEngine.SceneManagement; public class GameManager : MonoBehaviour { public static GameManager instance; private NavMeshRebuilder navMeshRebuilder; [HideInInspector] public PlayerHealthUI playerHealthUI; // Tüm sahneler için ortak UI void Awake() { if (instance == null) { instance = this; DontDestroyOnLoad(gameObject); SceneManager.sceneLoaded += OnSceneLoaded; // Sahne yüklendiğinde çağrılacak } else { Destroy(gameObject); return; } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (scene.name != "MainMenu") { navMeshRebuilder = FindObjectOfType<NavMeshRebuilder>(); RestartLighting(); } else { navMeshRebuilder = null; } } void Start() { Time.timeScale = 1f; } private void RestartLighting() { DynamicGI.UpdateEnvironment(); RenderSettings.ambientIntensity = 1f; LightmapSettings.lightmapsMode = LightmapsMode.CombinedDirectional; } public void RestartGame() { Debug.Log("RestartGame() çağrıldı!"); // Debug için ekledim PlayerManager.instance?.RestartPlayer(); EnemyManager.instance?.ClearEnemies(); // Önce düşman listesini temizle EnemyManager.instance?.ResetEnemies(); navMeshRebuilder?.RebuildNavMeshes(); RestartLighting(); Time.timeScale = 1f; } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; // Hafıza sızıntısını önlemek için event'ten çık } }
RestartGameButton.cs
using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; public class RestartGameButton : MonoBehaviour { public GameObject backupCamera; // Yedek kamera referansı (Inspector'dan atanacak) public void RestartGameFromBeginning() { // Yedek kamerayı SceneLoader'a aktar SceneLoader.backupCamera = backupCamera; GameManager.instance.RestartGame(); StartCoroutine(RestartCoroutine()); } private IEnumerator RestartCoroutine() { yield return PersistentSceneLoader.instance.StartCoroutine(PersistentSceneLoader.EnsurePersistentSceneLoaded()); yield return SceneLoader.instance.StartCoroutine(SceneLoader.LoadSceneCoroutine(2)); } }
SceneLoader.cs
using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; public class SceneLoader : MonoBehaviour { public static GameObject backupCamera; // Yedek kamera referansı public static SceneLoader instance; // Singleton instance private void Awake() { if (instance == null) { instance = this; } else { Destroy(gameObject); } } public static void LoadScene(int sceneIndex) { instance.StartCoroutine(LoadSceneCoroutine(sceneIndex)); } // LoadScene functionu oyuna ozel yapilmis sceneload yapan functur bu funcu leavegamebutton, restartbutton vb. leri icin olusturulmustur. public static IEnumerator LoadSceneCoroutine(int sceneIndex) { if (sceneIndex == 1) // MainMenu'ye dönüş { DestroyPersistentObjects(); yield return PersistentSceneLoader.instance.StartCoroutine(PersistentSceneLoader.UnloadPersistentScene()); SceneManager.LoadScene(sceneIndex); } else { yield return instance.StartCoroutine(UnloadAllLevels()); yield return PersistentSceneLoader.instance.StartCoroutine(PersistentSceneLoader.EnsurePersistentSceneLoaded()); yield return SceneManager.LoadSceneAsync(sceneIndex, LoadSceneMode.Additive); if (backupCamera != null) { backupCamera.SetActive(true); } } } private static IEnumerator UnloadAllLevels() { for (int i = 0; i < SceneManager.sceneCount; i++) { Scene scene = SceneManager.GetSceneAt(i); if (scene.name != "PersistentScene" && scene.name != "MainMenu") { yield return SceneManager.UnloadSceneAsync(scene); } } } private static void DestroyPersistentObjects() { GameObject[] dontDestroyObjects = GameObject.FindObjectsOfType<GameObject>(); foreach (GameObject obj in dontDestroyObjects) { if (obj.scene.buildIndex == -1) { Destroy(obj); } } } }
内容的提问来源于stack exchange,提问作者nuray nasirzade
相关产品推荐
相关产品推荐

