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

从Update调用的Coroutine不生效,IEnumerator无法运行,问题出在哪?

问题根源与修复方案

核心问题

  1. PlayerPrefs持久化残留:你之前测试时触发过成就,PlayerPrefs.SetInt("Ach01", 12345)已经把值存在本地了,程序启动时PlayerPrefs.GetInt("Ach01")会直接读出这个旧值,导致ach01Code一开始就是12345。
  2. Update逻辑冗余:每帧都读取PlayerPrefs不仅没必要,还会覆盖你在协程里临时设置的ach01Code值。
  3. 无重复触发防护:没有判断achActive状态,可能导致协程被多次启动。
  4. 静态变量未初始化:ach01Count是static类型,场景重启或对象重建时会保留之前的数值,可能一开始就等于触发阈值5。

修复步骤

  1. 清理旧的PlayerPrefs数据(测试用,上线前移除):在Start方法里临时添加代码,清除之前存的成就值。
  2. 优化变量初始化逻辑:把ach01Code的读取移到Start,避免每帧重复读取;初始化ach01Count为0,防止静态变量残留。
  3. 添加重复触发防护:在判断条件里加入!achActive,避免协程被多次启动。
  4. 确保PlayerPrefs立即保存:在协程里设置完值后调用PlayerPrefs.Save()。

修改后的完整代码

using UnityEngine;
using UnityEngine.UI;

public class AchievementManager : MonoBehaviour
{
    // General Vars
    public GameObject achNotif;
    public AudioSource achSound;
    public bool achActive = false;
    public GameObject achTitle;
    public GameObject achText;

    // Collection Based (01)
    public GameObject ach01Image;
    public int ach01Count = 0; // 去掉static,初始化0
    public int ach01Trigger = 5;
    public int ach01Code;

    private void Start()
    {
        // 初始化时读取一次成就状态即可
        ach01Code = PlayerPrefs.GetInt("Ach01", 0); // 无键时返回默认值0
        
        // 测试用:清理旧的成就数据,上线前删除
        // PlayerPrefs.DeleteKey("Ach01");
        // PlayerPrefs.Save();
    }

    private void Update()
    {
        // 加!achActive防止重复触发协程
        if (ach01Count == ach01Trigger && ach01Code != 12345 && !achActive)
        {
            StartCoroutine(Trigger01Ach());
            Debug.Log("Achievement Collected!");
        }
    }

    IEnumerator Trigger01Ach()
    {
        achActive = true;
        ach01Code = 12345;
        PlayerPrefs.SetInt("Ach01", ach01Code);
        PlayerPrefs.Save(); // 确保立即写入本地

        achSound.Play();
        ach01Image.SetActive(true);
        achTitle.GetComponent<Text>().text = "COLLECTION!";
        achText.GetComponent<Text>().text = "Created A Collection Based Achievement";
        achNotif.SetActive(true);

        yield return new WaitForSeconds(7);

        // Reset UI
        achNotif.SetActive(false);
        ach01Image.SetActive(false);
        achTitle.GetComponent<Text>().text = "";
        achText.GetComponent<Text>().text = "";
        achActive = false;
    }

    // 收集道具时调用此方法
    public void CollectItem()
    {
        if (ach01Code != 12345) // 已解锁成就就不再计数
        {
            ach01Count++;
        }
    }
}

额外注意事项

  • 确保收集道具的逻辑正确调用CollectItem()方法,否则ach01Count不会增加。
  • 上线前务必移除测试用的PlayerPrefs.DeleteKey代码,避免清空玩家的成就数据。

内容的提问来源于stack exchange,提问作者Aaron Benson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 19:14:57