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优化
- 打开
Edit > Project Settings > Editor - 勾选「Enter Play Mode Options」
- 根据项目需求取消勾选「Reload Domain」或「Reload Scene」(注意:此方式需确保脚本在模式切换时状态正确,避免出现逻辑异常)
内容的提问来源于stack exchange,提问作者쭌이jjoon
相关产品推荐
相关产品推荐

