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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 01:07:47