Unity开发:商店金钱仅启动时开菜单才更新、购买头盔空引用问题
问题1:商店金钱UI不刷新问题
原因
你同时维护了GameControl.moneyAmount、PageOneShop.moneyAmount两套独立的静态金钱变量,且存在两个错误逻辑:
- 拾取金币时仅修改了内存中的静态变量值,没有写入PlayerPrefs持久化存储
- 若启动场景时商店处于关闭状态,PageOneShop脚本未激活,
Start方法不会执行;当你后续打开商店时,PageOneShop的Start方法会执行,直接调用PlayerPrefs.GetInt("MoneyAmount")读取到旧的数值,覆盖了内存中累加后的金币值,导致UI显示异常 - 启动场景时商店默认打开的情况下,PageOneShop的
Start已经提前执行过,后续开关商店如果是显隐操作而非销毁重建,不会再次触发Start读旧值,所以显示正常
修复方案
- 删掉冗余的全局金钱变量,仅保留
GameControl.moneyAmount作为全局唯一的金钱数值源,移除PageOneShop脚本中定义的public static int moneyAmount - 拾取金币时同步写入PlayerPrefs,修改
Coin脚本代码:
void OnTriggerEnter2D (Collider2D col) { GameControl.moneyAmount += 200; PlayerPrefs.SetInt("MoneyAmount", GameControl.moneyAmount); Destroy(gameObject); }
- 将
PageOneShop脚本中所有用到moneyAmount的地方全部替换为GameControl.moneyAmount,删除Start方法中读取MoneyAmount的逻辑,不需要单独维护商店内的金钱变量。
问题2:购买物品时「未将对象引用设置到对象的实例」报错
原因
GetComponent<T>()只会查找当前脚本挂载的游戏对象上的对应组件。你的PageOneShop脚本是挂在商店UI对象上的,PlayerHealth组件是挂在玩家对象上的,两者不属于同一个游戏对象,所以GetComponent<PlayerHealth>()返回空值,调用maxHealth属性就会触发空引用报错。
修复方案
通过标签查找玩家对象后再获取组件,修改所有购买方法中获取PlayerHealth的代码,以buyHelmet为例:
public void buyHelmet() { GameControl.moneyAmount -= 150; // 提前给玩家对象设置Tag为Player PlayerHealth playerHealth = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerHealth>(); playerHealth.maxHealth += 50; PlayerPrefs.SetInt("MoneyAmount", GameControl.moneyAmount); PlayerPrefs.SetInt("IsHelmetSold", 1); helmetPrice.text = "Sold!"; buyHelmetButton.gameObject.SetActive(false); }
如果你的玩家对象全局唯一,也可以将PlayerHealth做成单例,直接调用PlayerHealth.Instance.maxHealth += 50,性能和稳定性更好。
另外记得所有购买操作完成后都要把扣除后的金钱写入PlayerPrefs,避免切换场景后数值回滚。
内容的提问来源于stack exchange,提问作者FighterOne12344
相关产品推荐
相关产品推荐

