Unity中Checkpoint场景保存/加载及跨场景变量丢失问题求助
解决方案:跨场景保存Checkpoint场景与位置
问题根源
你直接存储Scene实例的方式行不通——Scene对象是Unity绑定当前加载场景的内部引用,当原场景被卸载(切换到死亡场景时),这个引用会失效变为null。必须改用场景名称/路径这类持久化的字符串标识来保存场景信息。
修改步骤
1. 重构静态保存类
把原来存储Scene实例的静态变量换成字符串类型,保存场景名称(或路径,避免重名场景冲突):
public class SaveScene { // 保存场景名称 public static string SavedSceneName { get; set; } // 同时把玩家位置也移到这里统一管理(可选,更规范) public static Vector2 LastCheckpointPos { get; set; } }
2. 更新Checkpoint触发逻辑
触发Checkpoint时,保存场景名称和位置,不再存储Scene实例:
public class Checkpoint : MonoBehaviour { private void OnTriggerEnter2D(Collider2D collision) { // 用CompareTag比直接读取Tag性能更优 if(collision.CompareTag("Player")) { // 保存当前场景名称 SaveScene.SavedSceneName = SceneManager.GetActiveScene().name; // 保存Checkpoint位置 SaveScene.LastCheckpointPos = transform.position; } } }
3. 实现重生逻辑
在死亡场景的重生代码中,通过保存的场景名称加载原场景,加载完成后设置玩家位置:
public class DeathSceneHandler : MonoBehaviour { // 比如点击重生按钮调用此方法 public void TriggerRespawn() { if(string.IsNullOrEmpty(SaveScene.SavedSceneName)) { // 没有保存的Checkpoint,可回到初始场景 SceneManager.LoadScene("InitialScene"); return; } // 加载保存的场景,并注册加载完成事件 SceneManager.sceneLoaded += OnRespawnSceneLoaded; SceneManager.LoadScene(SaveScene.SavedSceneName); } private void OnRespawnSceneLoaded(Scene loadedScene, LoadSceneMode mode) { // 解除事件绑定,避免重复触发 SceneManager.sceneLoaded -= OnRespawnSceneLoaded; // 找到玩家并设置重生位置 GameObject player = GameObject.FindGameObjectWithTag("Player"); if(player != null) { player.transform.position = SaveScene.LastCheckpointPos; } } }
额外注意事项
- 如果你之前使用
DontDestroyOnLoad标记Player,确保场景切换时不会重复生成Player实例(可以在Player的Awake方法里做单例判断)。 - 若项目中有重名场景,建议改用
SceneManager.GetActiveScene().path保存场景路径,加载时用SceneManager.LoadScene(路径),更可靠。
内容的提问来源于stack exchange,提问作者PawzyPuppy
相关产品推荐
相关产品推荐

