Unity场景间非跨游戏实例数据存储方案咨询
解决方案:场景间临时数据传递(非持久化)
PlayerPrefs是持久化存储,自然会留下残留导致刷XP问题,换成以下内存级的方案就行,程序关闭后数据自动清空:
1. 全局单例数据管理器(最常用)
写一个带单例模式的MonoBehaviour脚本,挂在一个空物体上,标记DontDestroyOnLoad,让它在场景切换时不销毁,专门存所有临时游戏数据。
示例代码:
using UnityEngine; using UnityEngine.SceneManagement; public class GameDataManager : MonoBehaviour { // 全局唯一实例 public static GameDataManager Instance; // 角色核心数据 public int PlayerCurrentHP; public int PlayerMaxHP; public int PlayerCurrentXP; // 战斗返回的临时XP,用完就清 public int TempBattleRewardXP; void Awake() { // 确保只有一个实例 if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } // 回到Overworld时自动清空临时XP void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (scene.name == "Overworld") { TempBattleRewardXP = 0; } } void OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded; } void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; } }
使用流程:
- Overworld场景启动时,把角色当前属性赋值给
GameDataManager.Instance对应的字段 - 进入Battle场景时,从
GameDataManager.Instance读取角色数据 - Battle结束后,把奖励XP赋值给
TempBattleRewardXP,然后切回Overworld - Overworld场景的角色初始化脚本里,先检查
TempBattleRewardXP,如果大于0就加到PlayerCurrentXP,之后立刻把TempBattleRewardXP设为0
重启游戏后,单例会重新创建,所有字段都是默认值,不会有残留的XP。
2. 静态临时数据容器(轻量方案)
如果不想用单例对象,直接写一个静态类存临时传递的数据,用完手动清空,程序重启后静态字段会自动重置为默认值。
示例代码:
// 临时数据容器,仅用于场景间传递 public static class SceneTransferData { // 战斗奖励XP public static int BattleRewardXP; // 角色数据(可自定义类存储更多属性) public static PlayerData CurrentPlayerData; // 用完清空,避免残留 public static void Clear() { BattleRewardXP = 0; CurrentPlayerData = null; } } // 自定义角色数据类 public class PlayerData { public int CurrentHP; public int MaxHP; public int CurrentXP; }
使用流程:
- Overworld切Battle前,把角色数据存入
SceneTransferData.CurrentPlayerData - Battle场景读取
CurrentPlayerData执行战斗逻辑 - Battle结束后,把奖励XP赋值给
BattleRewardXP,切回Overworld - Overworld启动时,检查
BattleRewardXP,有值就加到角色XP,然后调用SceneTransferData.Clear()
这个方案不需要额外的GameObject,代码更简洁,适合数据结构不复杂的情况。
3. 运行时创建ScriptableObject(适合复杂数据)
如果角色数据结构很复杂,用ScriptableObject的运行时实例存数据——注意不要用Assets里的持久化SO文件,必须在代码里动态创建,这样数据只存在内存中,关闭游戏就消失。
示例代码:
using UnityEngine; // 定义ScriptableObject模板 [CreateAssetMenu(fileName = "PlayerDataSO", menuName = "Game/Temp Player Data")] public class PlayerDataSO : ScriptableObject { public int CurrentHP; public int MaxHP; public int CurrentXP; public int TempBattleXP; } // 在Overworld中动态创建实例并传递 public class OverworldInit : MonoBehaviour { void Start() { // 动态创建临时实例 PlayerDataSO tempData = ScriptableObject.CreateInstance<PlayerDataSO>(); tempData.CurrentHP = 100; tempData.MaxHP = 150; // 通过静态类传递给Battle场景 SceneTransferData.PlayerDataSO = tempData; } }
注意:
动态创建的SO实例不会保存到本地,程序关闭后自动销毁,处理完奖励XP后直接丢弃实例即可,不用担心数据残留。
核心注意点
不管用哪种方案,核心都是把数据存在内存里,用完及时清空临时字段,避免场景切换或重启后重复读取。PlayerPrefs是持久化存储,本来就不适合这种临时数据传递的场景。
内容的提问来源于stack exchange,提问作者HGBadger
相关产品推荐
相关产品推荐

