Unity货币系统异常:金币被设为固定值而非累加,求修复
Unity货币系统问题修复:金币累加异常与场景单次奖励失效
核心问题
- 金币未按需求累加,表现为直接被设置为奖励数值
- 场景奖励在加载完成后立即发放,未实现“玩家碰撞终点线后才奖励”的逻辑
- 场景1的奖励数值与需求不符(代码中为300,需求是400)
- 未真正实现“每个场景仅能领取一次奖励”的预期(因为发放时机错误)
问题原因
- 奖励时机错误:
levelBeaten脚本的Start方法中直接执行了加金币和标记奖励已领取的逻辑,导致场景一加载就发奖,完全脱离了“碰撞终点线”的触发条件。 - 数值匹配错误:场景1的奖励数值代码写为300,与需求的400不一致。
- 重复领取校验逻辑位置错误:校验逻辑放在
Start中,无法在玩家碰撞终点时再次确认是否已领取(比如场景重启后可能出现的异常情况)。
修复方案
- 将奖励发放和校验逻辑从
Start方法移到levelfinishedpopup方法内,确保只有玩家碰撞终点后才触发奖励。 - 修正场景1的奖励数值为400。
- 在发放奖励前重新执行领取状态校验,避免异常场景下的重复发放。
修改后的代码
主脚本(levelBeaten)
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class levelBeaten : MonoBehaviour { public GameObject finishCollider; public GameObject finishPopup; public currencyHandler currency; private int sceneIndex; void Start() { sceneIndex = SceneManager.GetActiveScene().buildIndex; finishPopup.SetActive(false); Time.timeScale = 1f; } void Update() { } void OnCollisionEnter(Collision collision) { if (collision.gameObject.tag == "Player") { levelfinishedpopup(); } } public void levelfinishedpopup() { finishPopup.SetActive(true); Animator animator = GetComponentInChildren<Animator>(); animator.SetTrigger("popupAnimation"); // 触发奖励逻辑 GrantSceneReward(); float animationLength = animator.GetCurrentAnimatorStateInfo(0).length; StartCoroutine(WaitAndStopTime(animationLength)); } private void GrantSceneReward() { // 检查当前场景奖励是否已领取 if (PlayerPrefs.HasKey("GoldClaimedInScene" + sceneIndex)) { Debug.Log("当前场景奖励已领取:" + sceneIndex); return; } // 根据场景索引设置奖励数值 int goldToAdd = sceneIndex == 1 ? 400 : sceneIndex == 2 ? 500 : 0; if (goldToAdd > 0) { currency.AddGold(goldToAdd); PlayerPrefs.SetInt("GoldClaimedInScene" + sceneIndex, 1); PlayerPrefs.Save(); Debug.Log("已发放场景奖励:" + goldToAdd + "金币"); } } private IEnumerator WaitAndStopTime(float waitTime) { yield return new WaitForSeconds(waitTime); Time.timeScale = 0f; } }
货币处理器(currencyHandler)
using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; public class currencyHandler : MonoBehaviour { public int gold = 0; public GameObject currencyUI; private TextMeshProUGUI currencyText; private const string GOLD_KEY = "gold"; void Start() { currencyText = currencyUI.GetComponent<TextMeshProUGUI>(); LoadGold(); } void Update() { currencyText.text = "Gold: " + gold.ToString(); if (gold < 0) { gold = 0; } } public void AddGold(int amount) { gold += amount; SaveGold(); } private void SaveGold() { PlayerPrefs.SetInt(GOLD_KEY, gold); PlayerPrefs.Save(); } private void LoadGold() { gold = PlayerPrefs.GetInt(GOLD_KEY, 0); } }
额外说明
- 货币处理器的
AddGold方法逻辑本身是正确的累加操作,之前的“直接设置”表现是因为场景加载就发奖的逻辑错误导致的误解。 - 修改后只有玩家碰撞终点线时才会触发奖励发放,且每个场景仅能领取一次。
内容的提问来源于stack exchange,提问作者Nicholas Gounaris
相关产品推荐
相关产品推荐

