Unity - 如何在无限循环的情况下停止播放模式?
Posted
技术标签:
【中文标题】Unity - 如何在无限循环的情况下停止播放模式?【英文标题】:Unity - How to stop Play Mode in case of infinite loop? 【发布时间】:2017-08-31 10:12:37 【问题描述】:我只是犯了一个愚蠢的错误,在 void Update()
内部而不是写 if(var)
我写了 while(var)
并且 var
在 while 内部从未被修改过,所以我最终在我的 @ 中编写了一个无限循环987654326@
故事本身并不重要。重要的是我无法停止播放模式。实际上,在我重新启动之前,我无法使用 Unity 做任何其他事情。
所以我的问题是,有人知道如何优雅地停止 Unity 中的播放模式吗?是否有任何快捷方式或某些代码行来强制超时?
我知道最好的方法是避免无限循环,但有些东西你可能会犯一个愚蠢的错字。
额外说明:我一直在寻找解决这个问题的方法,很遗憾没有成功。但是,我找到了解决此问题的副作用的方法。当您按下 ctrl-alt-del 时,您可以释放场景中尚未保存的所有内容(这可能需要数小时的工作)。
所以当你点击播放时 Unity 会自动保存,并且场景备份在 Temp folder
中,只要你在强制退出后没有再次运行 Unity。
【问题讨论】:
你不能来自 Unity 本身。发生这种情况时,您必须从任务管理器中杀死 Unity。发布导致该问题的代码,您可能会得到答案。 感谢您的回答。实际上我自己发现了问题,正如我在问题中所说的那样,我写了一个 while() 而不是 if() 用于测试的东西我一直保持真实。 我自己从来没有用过,但是有一个(付费的)asset on the store 在这种情况下阻止 Unity。 【参考方案1】:以下内容对我有用(@LinusR 和扩展 @Kinxil 的道具)这只是一个快速的分步。
如果您使用带有 Unity 工具的 Visual Studio,这应该适合您。
找到循环:
-
打开 Visual Studio(如果尚未打开)
点击附加到 Unity(如果尚未附加)
点击Break All(暂停II符号)
打开调用堆栈、线程和立即窗口。 (全部在调试 → Windows →)
查看调用堆栈,点击线程窗口中的线程。
当您找到循环所在的线程时停止。 (调用堆栈对此有帮助)
您必须在带有循环的线程上才能在 立即 窗口中执行必要的命令。
现在让我离开这里!:
[LinusR 的解决方案似乎是最防弹和通用的。]
用空值和其他一些选项打破循环
-
在 立即 窗口中,将循环中使用的可空对象/字段/属性之一设置为 null,例如对于
Thread.SpinWait.SpinUntil(() => someObject.NeverTrue());
someObject = null;
Unity 将在这种情况下再次响应(假设 someObject 保持为空)。
某些循环的替代方法是简单地中断和更改指令或值和/或将当前指令箭头(黄色箭头)拖出循环,但这可能无法实现,具体取决于循环类型。
想想循环是如何工作的;它多久执行一次?它会被称为每一帧吗?等
没有工作?在此处阅读其他答案,利用即时窗口发挥创意。此外,在 Unity 中始终启用 错误暂停 也是明智之举。
【讨论】:
【参考方案2】:我刚遇到这种情况:意外无限循环,在未保存工作的场景中卡在播放模式,Unity 无响应。
但我很幸运能够打开 Monodevelop,尽管我主要使用 Sublime 编写脚本。我在 Monodevelop 窗口左上角附近按下按钮开始调试,然后按下暂停按钮。执行在我的无限循环中间的一行暂停。 Windows 任务管理器确认 Unity 不再锁定 CPU。
然后,在 Monodevelop 中,我能够找到一个对象 obj
,下一行将尝试对其进行方法调用,并使用“立即”窗口执行 obj = null
。然后取消暂停。由于空指针错误,Unity 本身现在已解锁,我可以将其退出播放模式并保存我的工作。
(Unity 2017.4.1f1 Personal、Windows 10 Home x64、Monodevelop 5.9.6)
注意,我从阅读@Kinxil 的答案中得到了这个想法,但我不得不采取稍微不同的方法,因为没有“阻塞值”。我有一个 for (;;)
循环,该循环以前在协程内,我将其更改为 FixedUpdate()
内而不删除循环。 :\ 所以导致异常是我能想到的唯一选择。
【讨论】:
【参考方案3】:解决方案
-
将您的 IDE 连接到 Unity
暂停执行
退出循环
可选择执行 Debug.Break() 以防止循环在下一次 Update() 时再次进入
恢复执行
返回 Unity 编辑器
对于 Visual Studio
(我还没有测试过其他 IDE)
-
单击附加到 Unity
等待进程附加(有时需要一段时间)
点击全部中断(暂停II符号)
点击菜单调试 → Windows → 线程
单击包含您的源代码的线程(参见位置列)
在您的源代码(文本编辑器)中,通过将程序指针(黄色箭头)拖动到源代码中的不同行,将其移到循环之外。
可选地,如果循环位于某个 Update() 事件中,该事件将再次重新进入循环:
-
点击菜单调试 → Windows → 立即
在即时窗口中输入
UnityEngine.Debug.Break()
并按 Enter
最后恢复执行(播放按钮)并返回 Unity 编辑器。 Unity 现在应该处于“暂停”状态,您可以在其中检查出了什么问题或“停止”播放模式。
【讨论】:
【参考方案4】:对我来说,这很有效。
如何摆脱无限循环
-
打开 Visual Studio。
点击顶部的“附加到 Unity”(如果尚未点击)
通过单击循环所在行号左侧的区域,向无限循环添加断点。
您会在断点所在的位置看到一个黄色箭头。单击此箭头并将其拖动到循环之外的位置(最好在之后)
删除当前断点。
回到统一状态,解冻可能需要一秒钟,但解冻后,您应该可以单击播放按钮停止播放模式。
轰隆隆!避免了惊恐发作。
【讨论】:
【参考方案5】:很遗憾,虚幻引擎在很大程度上非常擅长检测无限循环并在它们发生时退出,但 Unity 似乎从来没有。很难找出发生了什么,因为Debug.Log
在帧完成之前不会触发,所以你看不到发生了什么。尝试查看发生了什么的解决方法是使用某种限制器,如下所示:
int limiter = 0, loopCap = 10000;
while (SomeCondition && limiter < loopCap)
// Do something
limiter++
if (limiter >= loopCap) Debug.Log("Infinite Loop avoided");
当然,这是一个更简单的例子,因为while
循环很容易变成无限循环,但如果你有一个可能发生的地方,你可以在那里放一个限制器。
这仅用于调试目的,因此您不必通过任务管理器取消它。理想情况下,您可以找出问题所在并移除限制器。
几天前我有一个无限循环,我不知道哪里出了问题,所以我只是注释掉了代码然后取消注释它直到它再次崩溃,并且能够弄清楚它来自哪里.
【讨论】:
以上是关于Unity - 如何在无限循环的情况下停止播放模式?的主要内容,如果未能解决你的问题,请参考以下文章