You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 10:03:21