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

启用Timer脚本时Unity PlayMode冻结编辑器的原因分析

Unity PlayMode冻结问题排查与修复

你的脚本核心问题是难度判断的嵌套逻辑完全错误,虽然协程中的while(true)搭配yield return null不会直接造成主线程无限阻塞,但错误的逻辑会导致状态混乱,甚至引发连锁反应(比如频繁修改BlockSpawner.timeBetweenWaves导致生成逻辑异常),最终造成编辑器卡死。

逻辑错误分析

  1. 最外层if(dif == 1)分支内,嵌套了if(dif == 2)和if(dif == 3)判断——这些判断永远不可能成立,因为外层已经限定了dif == 1,完全属于无效逻辑。
  2. 当dif为2或3时,会进入最外层的else分支,一旦sec == 30就会强制把dif重置为1,导致难度提升逻辑完全失效,还可能引发频繁的状态切换。

修复后的代码

using System.Collections;
using UnityEngine;
using TMPro;

public class Timer : MonoBehaviour
{
    public TMP_Text timer;
    public TMP_Text DifTextpro;
    public float time;
    float sec;
    float min;
    public static float dif = 0;
    public string diftext;

    private void Start()
    {
        StartCoroutine(StopWatch());
        BlockSpawner.timeBetweenWaves = Random.Range(5.2f, 6f);
    }

    IEnumerator StopWatch()
    {
        while (true)
        {
            time += Time.deltaTime;
           
            sec = (int)(time % 60);
            min = (int)(time / 60 % 60);

            timer.text = string.Format("{0:00} : {1:00}", min, sec);

            // 按时间顺序依次判断难度提升条件,避免嵌套逻辑混乱
            if (dif == 0)
            {
                if (sec == 30)
                {
                    dif = 1;
                    diftext = "Normal";
                    DifTextpro.text = diftext;
                    BlockSpawner.timeBetweenWaves = Random.Range(4f, 5.2f);
                }
            }
            else if (dif == 1)
            {
                if (min == 1 && sec == 15)
                {
                    dif = 2;
                    diftext = "Hard";
                    DifTextpro.text = diftext;
                    BlockSpawner.timeBetweenWaves = Random.Range(3f, 4f);
                }
            }
            else if (dif == 2)
            {
                if (min == 2 && sec == 30)
                {
                    dif = 3;
                    diftext = "Very Hard";
                    DifTextpro.text = diftext;
                    BlockSpawner.timeBetweenWaves = Random.Range(2f, 3f);
                }
            }
            else if (dif == 3)
            {
                if (min == 4 && sec == 15)
                {
                    diftext = "Extreme";
                    DifTextpro.text = diftext;
                    BlockSpawner.timeBetweenWaves = Random.Range(1.2f, 2f);
                }
            }

            yield return null;
        }
    }
}

修复说明

  1. 将嵌套的if改为顺序的else if,逻辑清晰,避免无效判断。
  2. 每个难度阶段只判断对应阶段的提升条件,不会出现跨阶段的错误重置。
  3. 移除了无用的msec变量,简化代码。
  4. 改用方法名直接启动协程(StartCoroutine(StopWatch())),避免反射调用的潜在问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 08:40:25