Unity - 如何在无限循环的情况下停止播放模式?

时间:2017-08-31 10:12:38

标签: c# unity3d

我只是犯了一个愚蠢的错误而且在void Update()内而不是写if(var)我写了while(var)而且var从未修改过,所以我结束了在我的Update()

中编写一个无限循环

故事本身并不重要。重要的是我无法停止播放模式。实际上,在重新启动之前,我无法用Unity做任何其他事情。

所以我的问题是,有没有人知道如何优雅地停止Unity中的播放模式?是否有任何快捷方式或某些代码行强制超时?

我知道最好的方法是避免无限循环,但有些事情你可以做出愚蠢的错字。

额外注意:我一直在寻找这个问题的解决方案,但遗憾的是没有成功。但是我找到了这个问题的副作用的解决方案。当您按下ctrl-alt-del时,您可以放弃在场景中保存的所有内容(可能需要数小时)。

所以当你点击播放时Unity会自动保存,并且场景备份在Temp folder,只要你在强制退出后没有再次运行Unity。

6 个答案:

答案 0 :(得分:4)

对我来说,这行得通。

如何摆脱无限循环

  1. 打开Visual Studio。
  2. 单击顶部的“附加到Unity”(如果尚未单击)
  3. 通过单击循环所在行号左侧的区域,将断点添加到无限循环中。
  4. 您将在断点处看到一个黄色箭头。单击并拖动此箭头到循环外的某个位置(最好在之后)
  5. 删除当前断点。
  6. 恢复到统一状态,最有可能需要一秒钟的时间来冻结,但是在冻结之后,您应该可以单击播放按钮以停止播放模式。
  7. 轰!避免了惊恐发作。

答案 1 :(得分:1)

我刚刚遇到这种情况:意外无限循环,在未保存的工作场景中陷入播放模式,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()内部,而不删除循环。 :\因此导致异常是我能想到的唯一选择。

答案 2 :(得分:1)

令人遗憾的是,虚幻引擎在很大程度上非常擅长检测无限循环并在它们出现时退出,但Unity几乎从未出现过。很难找出发生了什么,因为?+在帧完成之前不会触发,所以你无法看到发生了什么。尝试查看正在发生的事情的解决方法是使用某种类似的限制器:

\\%

当然,这是一个更简单的例子,因为Debug.Log循环很容易变成无限循环,但是如果你有一个可以发生的地方的球场,你可以在那里设置一个限制器。

这仅用于调试目的,因此您无需通过任务管理器取消它。理想情况下,您可以找出问题所在并删除限制器。

几天前我有一个无限循环,我不知道它出错的地方,所以我只是注释掉了代码然后取消注释掉它直到它再次破坏,并且能够找出它来自哪里。

答案 3 :(得分:1)

以下内容对我有用(对@LinusR的支持,并通过@Kinxil的扩展),这只是一个快速的分步说明。

如果您使用带有Unity工具的Visual Studio,这应该对您有用。

查找循环:

  1. 打开Visual Studio(如果尚未打开)
  2. 点击附加到Unity (如果尚未附加)
  3. 点击全部破坏(暂停 II 符号)
  4. 打开调用堆栈线程立即窗口。 (全部在 Debug→Windows→中)
  5. 查看调用堆栈,单击线程窗口中的线程。
  6. 在找到循环所在的线程时停止。 (调用堆栈可帮助解决此问题)
  7. 您必须处于循环状态,才能在立即窗口中执行必要的命令。

现在让我离开这里!:

[LinusR的解决方案似乎是最防弹和最通用的。]

使用空值和其他一些选项中断循环

  1. 立即窗口中,将循环中使用的可为空的对象/字段/属性之一设置为 null ,例如为Thread.SpinWait.SpinUntil(() => someObject.NeverTrue());
    • someObject = null;
    • 在这种情况下,Unity将再次响应(假设someObject保持为空)。
  2. 某些循环的另一种选择是简单地中断和更改指令或值和/或将当前指令箭头(黄色箭头)拖出循环,尽管这可能无法实现,具体取决于循环类型。
    • 考虑循环的工作方式;多久执行一次?会被称为每一帧吗?等
  3. 什么都没做?在此处阅读其他答案,使用立即窗口发挥创意。同样,将来最好始终在Unity中启用错误暂停

答案 4 :(得分:1)

解决方案

  1. 将您的IDE附加到Unity
  2. 暂停执行
  3. 退出循环
  4. (可选)执行Debug.Break()以防止循环在下一个Update()处再次进入
  5. 恢复执行
  6. 返回Unity编辑器

对于Visual Studio

(我尚未测试其他IDE)

  1. 点击附加到Unity
  2. 等待过程附加(有时需要一段时间)
  3. 点击全部突破(暂停 II 符号)
  4. 单击菜单调试→Windows→线程
  5. 单击包含您的源代码的线程(请参见位置列)
  6. 在源代码(文本编辑器)中,将程序指针(黄色箭头)拖动到源代码中的另一行,将其移到循环外。

(可选)如果循环位于某个Update()事件内部,该事件将再次重新进入循环:

  1. 点击菜单调试→Windows→立即
  2. 在立即窗口中输入2019-12-02T03:35:44.0496478Z {"@t":"2019-12-02T03:35:44.0301714Z","@m":"The path provided is invalid.","@i":"05178f7d","@l":"Error","SourceContext":"ArtifactTool.Program","UtcTimestamp":"2019-12-02 03:35:44.030Z"} 2019-12-02T03:35:44.0776082Z ##[error]Error: An unexpected error occurred while trying to push the package. Exit code(16) and error({"@t":"2019-12-02T03:35:43.3152933Z","@m":"ApplicationInsightsTelemetrySender will correlate events with X-TFS-Session 23e076ea-5122-4c06-b92a-2aef5974defd","@i":"8778ba0f","SourceContext":"ArtifactTool.Commands.UPackPublishCommand","UtcTimestamp":"2019-12-02 03:35:43.315Z"} ,然后按Enter

最后恢复执行(“播放”按钮)并返回Unity编辑器。 现在,Unity应该处于“已暂停”状态,您可以在其中检查出了什么问题或“停止”了播放模式。

答案 5 :(得分:0)

愚蠢的回答:不要做无限循环。提供给你的无限循环疼痛会告诉你不要再这样做了。

Rocket启动器可能性:将Unity绑定到Visual Studio或Mono Develop,使用暂停按钮并手动修改阻止值以使其停止。

否则,您可以通过进程终止来使其变脏。