Unity中非静态Float变量存入PlayerPrefs后重启归零如何修复?
问题核心原因
你的代码存在两个直接导致存储失败的问题:
- 加载逻辑判断条件完全错误:你
LoadGame方法中判断存档是否存在的key是SavedInteger,但你全程存储的key只有mainmoney和destroy,没有任何地方存过SavedInteger,所以每次启动游戏都会走else分支,根本不会执行加载逻辑,自然变量会重置为初始值0。 - 非静态变量的引用/实例丢失风险:你没有确保
COINS类的实例cors在场景加载过程中不会被销毁、引用不会丢失,每次重启游戏后如果cors是挂载在场景对象上的组件,初始值就是0,又没有被加载逻辑赋值,自然就会恢复成0。
解决方案
第一步:修复加载判断逻辑
把LoadGame里的判断条件改成你实际存储的key即可,建议新增专门的存档存在标记key,避免判断逻辑混乱。
第二步:确保非静态实例的有效性
两种可选方案,都不需要用静态变量:
- 方案1:给挂载
COINS组件的对象加DontDestroyOnLoad,确保它不会在场景切换、重启时被销毁,同时在Inspector面板给savegameprogress2的cors字段正确拖入对应的COINS组件实例,保证引用不会丢失。 - 方案2:用ScriptableObject存储
Destroyers数值,ScriptableObject是资源文件,本身就是独立于MonoBehaviour的持久化数据容器,不需要静态修饰也能跨场景、跨启动保留引用。
修改后的参考代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityStandardAssets.CrossPlatformInput; using UnityEngine.UI; using TMPro; public class savegameprogress2 : MonoBehaviour { public COINS cors; private void Start() { LoadGame(); Debug.Log(cors.Destroyers); } void Update() { if (Input.GetKeyDown(KeyCode.S)) { SaveGame(); } } public void SaveGame() { PlayerPrefs.SetFloat("mainmoney", COINS.gamecoin ); PlayerPrefs.SetFloat("destroy", cors.Destroyers); // 新增存储标记key,和判断逻辑对应 PlayerPrefs.SetInt("HasSave", 1); PlayerPrefs.Save(); Debug.Log("Game data saved!"); } void LoadGame() { // 改成和存储对应的标记key判断 if (PlayerPrefs.HasKey("HasSave")) { COINS.gamecoin = PlayerPrefs.GetFloat("mainmoney"); cors.Destroyers = PlayerPrefs.GetFloat("destroy"); } else { Debug.LogError("There is no save data!"); } } }
验证步骤
修改完成后按以下流程测试即可:
- 碰撞金币给
cors.Destroyers赋值1后按S触发存档 - 重启游戏,查看Start方法输出的
cors.Destroyers数值是否为1
内容的提问来源于stack exchange,提问作者Habib Ismail
相关产品推荐
相关产品推荐

