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

Unity切换至Application.EnterPlayMode时卡顿,请求排查原因

EnterPlayMode切换卡顿问题排查及修复

问题场景

  • 系统:Windows 10
  • Unity版本:2021.3.15f1(后更换为2021.3.17f1)
  • 项目:「포둥」
  • 触发条件:添加podungsay脚本后,切换至Application.EnterPlayMode
  • 现象:卡顿,提示“waiting for Unity's code to finish executing”,无法继续操作

问题根源

脚本中的mouth()协程存在无终止条件的无限循环:

IEnumerator mouth()
{
    while (true) // 永久循环,无退出逻辑
    {
        while (sayingf == true)
        {
            openmouth.SetActive(false);
            closemouth.SetActive(true);
            yield return new WaitForSeconds(0.7f);
            openmouth.SetActive(true);
            closemouth.SetActive(false);
            yield return new WaitForSeconds(0.7f);
        }
        openmouth.SetActive(true);
        closemouth.SetActive(false);
    }
}

Unity切换至EnterPlayMode时,会等待所有正在运行的协程执行完毕才进入播放模式。该协程从Start()启动后进入永久循环,永远无法结束,导致Unity持续等待,最终引发卡顿。

修复方案

方案1:给协程添加终止逻辑

方式A:在对象销毁时停止协程

修改脚本,记录协程引用并在对象销毁时终止:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class podungsay : MonoBehaviour
{
    public GameObject Textbox;
    public bool sayingf;
    public UnityEngine.UI.Text sayingtext;
    public GameObject openmouth;
    public GameObject closemouth;
    private Coroutine _mouthCoroutine; // 新增协程引用

    IEnumerator OnType(float interval, string Say, float wait)
    {
        sayingf = true;
        foreach (char item in Say)
        {
            sayingtext.text += item;
            yield return new WaitForSeconds(interval);
        }
        yield return new WaitForSeconds(wait);
        sayingf = false;
    }

    void Update()
    {
        Textbox.SetActive(sayingf); // 简化判断逻辑
    }

    IEnumerator mouth()
    {
        while (true)
        {
            while (sayingf == true)
            {
                openmouth.SetActive(false);
                closemouth.SetActive(true);
                yield return new WaitForSeconds(0.7f);
                openmouth.SetActive(true);
                closemouth.SetActive(false);
                yield return new WaitForSeconds(0.7f);
            }
            openmouth.SetActive(true);
            closemouth.SetActive(false);
            yield return null; // 增加帧等待,避免空循环占用资源
        }
    }

    void Start()
    {
        _mouthCoroutine = StartCoroutine(mouth()); // 记录协程
    }

    void OnDestroy()
    {
        if (_mouthCoroutine != null)
        {
            StopCoroutine(_mouthCoroutine); // 销毁时终止协程
        }
    }
}

方式B:在协程内部判断对象状态

替换永久循环为对象活跃状态判断:

IEnumerator mouth()
{
    // 仅当对象在层级中活跃时执行循环
    while (gameObject.activeInHierarchy)
    {
        while (sayingf == true && gameObject.activeInHierarchy)
        {
            openmouth.SetActive(false);
            closemouth.SetActive(true);
            yield return new WaitForSeconds(0.7f);
            openmouth.SetActive(true);
            closemouth.SetActive(false);
            yield return new WaitForSeconds(0.7f);
        }
        openmouth.SetActive(true);
        closemouth.SetActive(false);
        yield return null; // 避免空循环占用CPU
    }
}

方案2:启用Enter Play Mode Options优化

  1. 打开Edit > Project Settings > Editor
  2. 勾选「Enter Play Mode Options」
  3. 根据项目需求取消勾选「Reload Domain」或「Reload Scene」(注意:此方式需确保脚本在模式切换时状态正确,避免出现逻辑异常)

内容的提问来源于stack exchange,提问作者쭌이jjoon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 11:10:20