Unity C#商店脚本问题:购买时被重复收取所有商品费用
商店脚本错误分析与修复方案
核心错误原因
- 重复绑定确认按钮事件:每个商品面板的
ShopLogic脚本在Start方法中,都给同一个confirmButton添加了ConfirmClick监听。当点击确认购买时,三个ShopLogic实例的ConfirmClick会被依次触发,每个实例都会扣除自身的currentPrice,导致出现连续扣除10、20、30金币的问题。 - 逻辑判断时机错误:
itemClick方法中用playerCoins >= currentPrice判断金币是否足够,但currentPrice是在Confirm方法才赋值,首次点击时currentPrice为默认值0,判断逻辑完全失效。 - 冗余的组件获取:每个
ShopLogic实例自己的itemName、itemPrice等字段已在Inspector中设置,却额外从data对象的ShopLogic组件重复获取,属于无效操作。
修复后的代码示例
using UnityEngine; using UnityEngine.UI; using TMPro; public class ShopLogic : MonoBehaviour { public string itemName; public string itemDescription; public int itemPrice; public bool ownsItem; [Header("商品UI组件")] public TextMeshProUGUI buttonTitle; public TextMeshProUGUI buttonDescription; public TextMeshProUGUI buttonPrice; public Button purchaseButton; [Header("确认弹窗组件")] public GameObject confirmCanvas; public TextMeshProUGUI confirmItemTitle; public TextMeshProUGUI confirmDescription; public Button confirmButton; public PlayerValues playerStats; // 静态变量记录当前选中的商品实例 private static ShopLogic _currentSelectedItem; void Start() { ownsItem = false; // 直接用自身配置初始化商品UI buttonTitle.text = itemName; buttonDescription.text = itemDescription; buttonPrice.text = itemPrice.ToString(); // 绑定当前商品的购买按钮事件 purchaseButton.onClick.AddListener(OnPurchaseButtonClick); // 确认按钮仅绑定一次事件,避免重复触发 if (confirmButton.onClick.GetPersistentEventCount() == 0) { confirmButton.onClick.AddListener(ConfirmPurchase); } confirmCanvas.SetActive(false); } private void OnPurchaseButtonClick() { if (playerStats.Cash >= itemPrice) { _currentSelectedItem = this; // 更新确认弹窗内容 confirmItemTitle.text = itemName; confirmDescription.text = itemDescription; confirmCanvas.SetActive(true); } else { Debug.Log("金币不足,无法购买"); } } private void ConfirmPurchase() { if (_currentSelectedItem == null) return; // 扣除当前选中商品的价格 _currentSelectedItem.playerStats.Cash -= _currentSelectedItem.itemPrice; _currentSelectedItem.ownsItem = true; Debug.Log($"已扣除{_currentSelectedItem.itemPrice}金币"); // 隐藏弹窗并清空选中记录 confirmCanvas.SetActive(false); _currentSelectedItem = null; } }
额外优化建议
- 移除无用依赖:删除
using System.Data.Db;、using Unity.VisualScripting;等未使用的命名空间,减少编译负担。 - 直接赋值UI引用:在Inspector面板直接拖拽绑定
buttonTitle、purchaseButton等组件,避免用transform.Find查找,降低出错概率。 - 修正拼写错误:将
ConformationTab改为正确的ConfirmationTab,避免命名混淆。 - 添加状态反馈:购买成功后,隐藏购买按钮并显示“已拥有”文本,提升用户体验。
- 持久化商品状态:用
PlayerPrefs或本地文件存储ownsItem的值,避免重启游戏后丢失购买记录。
内容的提问来源于stack exchange,提问作者Tom W
相关产品推荐
相关产品推荐

