Unity C# 使用PlayerPrefs后定时更新数值不生效问题咨询
问题原因
- 计时逻辑错误:Update中
timeValue_budget -= PlayerPrefs.GetFloat("bud_time", Time.deltaTime);的写法完全不符合持久化计时的设计逻辑。PlayerPrefs中的值在你主动调用Set方法更新前是固定不变的,如果你曾经存储过bud_time为非Time.deltaTime的数值(比如触发过更新后赋值的30),那么每帧都会扣除固定值,要么直接把时间扣到0进入死循环,要么计时速度完全不符合预期,永远到不了触发更新的阈值。 - 数值更新后未回写持久化:
covid_budget()函数仅从PlayerPrefs读取C_B的值,但是数值计算更新后没有把新的Covid_Budget调用SetInt写回PlayerPrefs,导致每次读取的都是旧值,看起来就像没有更新。 - 冗余逻辑造成显示偏差:
DisplayTime_budget中timeToDisplay_b += 1的逻辑会导致显示时间比实际剩余时间多1秒,容易干扰问题排查。
修复方案
逻辑调整说明
你需要在游戏启动时仅读1次持久化的剩余时间,运行时正常用Time.deltaTime倒计时,仅在游戏退出/切后台时存储当前剩余时间,不要每帧读取PlayerPrefs。同时数值更新后必须同步写回PlayerPrefs,才能保证持久化的是最新值。
修正后完整代码
初始化逻辑
private void Start() { // 启动时读取上次存储的剩余计时,无历史记录则用默认30秒 timeValue_budget = PlayerPrefs.GetFloat("bud_time", 30); // 启动时先同步一次当前预算值 covid_budget(); }
Update计时逻辑
void Update() { if (timeValue_budget > 0) { // 正常按帧倒计时,不要每帧读PlayerPrefs timeValue_budget -= Time.deltaTime; } else { // 重置计时为30秒 timeValue_budget = 30; // 触发预算更新 covid_budget(); // 同步存储重置后的计时,避免切后台直接丢失 PlayerPrefs.SetFloat("bud_time", timeValue_budget); PlayerPrefs.Save(); } DisplayTime_budget(timeValue_budget); }
预算更新函数
public void covid_budget() { // 计算新的预算值 Covid_Budget = (int)(0.01 * economy_worth); // 写回PlayerPrefs持久化 PlayerPrefs.SetInt("C_B", Covid_Budget); PlayerPrefs.Save(); // 更新UI显示 CovidBudget.text = Covid_Budget.ToString(); }
倒计时显示函数
public void DisplayTime_budget(float timeToDisplay_b) { // 直接钳位到0即可,移除冗余的+1逻辑 timeToDisplay_b = Mathf.Max(0, timeToDisplay_b); float minutes = Mathf.FloorToInt(timeToDisplay_b / 60); float seconds = Mathf.FloorToInt(timeToDisplay_b % 60); TimerText_budget.text = string.Format("{0:00}:{1:00}", minutes, seconds); }
切后台/退出时存储计时(可选,避免中途退出丢失计时进度)
private void OnApplicationPause(bool pause) { if (pause) { PlayerPrefs.SetFloat("bud_time", timeValue_budget); PlayerPrefs.Save(); } } private void OnApplicationQuit() { PlayerPrefs.SetFloat("bud_time", timeValue_budget); PlayerPrefs.Save(); }
内容的提问来源于stack exchange,提问作者Muhammad Usama
相关产品推荐
相关产品推荐

