Unity 程序因无限 while 循环而停止响应

Unity program stopped responding because of a infinite while loop

你好堆栈溢出用户!我正在 unity 2018.2.2f1 中创建游戏。一切顺利,但我在程序中放错了代码行的顺序 --> 这导致出现无限循环。我不知道它会是无限的,所以我运行了程序。现在我的unitywindow点击图标就不能选了,进入window就全部冻结了。我会通过任务管理器关闭程序,但我没有保存我的文件,我什至无法保存项目。处于这种状态时,我有什么办法可以保存项目吗?我的团结没有崩溃,它只是冻结了。 这是我的 FIXED c# 代码,如果有帮助的话(我在 visual studio):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour {

    public float speed = 10f;
    private Vector3 velocity = new Vector3();
    private string direction = "none";
    private bool canMoveAgain = true;
    private bool go = false;
    // Use this for initialization
    void Start () {
        speed = 10f;
    }

    // Update is called once per frame
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.collider.name == "wall (3)" && direction == "down")
        {
            go = false;
        }
        if (collision.collider.name == "wall (2)" && direction == "up")
        {
            go = false;
        }
        if (collision.collider.name == "wall" && direction == "left")
        {
            go = false;
        }
        if (collision.collider.name == "wall (1)" && direction == "right")
        {
            go = false;
        }
    }
    void Update () {
        if (Input.GetKeyDown(KeyCode.DownArrow) && canMoveAgain)
        {
            direction = "down";
            go = true;
            canMoveAgain = false;
            while (go)
            {
                velocity = new Vector3(0,-1,0);
                transform.position += velocity;
            }
            velocity = new Vector3(0, 0, 0);
            direction = "none";
        } else if (Input.GetKeyDown(KeyCode.UpArrow) && canMoveAgain)
        {
            direction = "up";
            go = true;
            canMoveAgain = false;
            while (go)
            {
                velocity = new Vector3(0, +1, 0);
                transform.position += velocity;
            }
            velocity = new Vector3(0, 0, 0);
            direction = "none";
        } else if (Input.GetKeyDown(KeyCode.LeftArrow) && canMoveAgain)
        {
            direction = "left";
            go = true;
            canMoveAgain = false;
            while (go)
            {
                velocity = new Vector3(-1, 0, 0);
                transform.position += velocity;
            }
            velocity = new Vector3(0, 0, 0);
            direction = "none";
        } else if (Input.GetKeyDown(KeyCode.RightArrow) && canMoveAgain)
        {
            direction = "right";
            go = true;
            canMoveAgain = false;
            while (go)
            {
                velocity = new Vector3(+1, 0, 0);
                transform.position += velocity;
            }
            velocity = new Vector3(0, 0, 0);
            direction = "none";
        }
    }
}

你会

while (go)
{
    velocity = new Vector3(+1, 0, 0);
    transform.position += velocity;
}

但是 go 在循环中 永远不会设置为 false

OnCollisionEnter 从未执行,因为 while 仍在执行 => 冻结。

因为 Update 无论如何都会在每一帧调用,你应该在检查输入后将该部分移动到单独的 if(go) 块..

private void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.collider.name == "wall (3)" && direction == "down"
        || collision.collider.name == "wall (2)" && direction == "up"
        || collision.collider.name == "wall" && direction == "left"
        || collision.collider.name == "wall (1)" && direction == "right")
    {
        go = false;
        velocity = Vector3.zero;
        direction = "none"
    }
}

void Update () 
{
    if (Input.GetKeyDown(KeyCode.DownArrow) && canMoveAgain)
    {
        direction = "down";
        go = true;
        canMoveAgain = false;
        velocity = -Vector3.up;
    } 
    else if (Input.GetKeyDown(KeyCode.UpArrow) && canMoveAgain)
    {
        direction = "up";
        go = true;
        canMoveAgain = false;
        velocity = Vector3.up;
    } 
    else if (Input.GetKeyDown(KeyCode.LeftArrow) && canMoveAgain)
    {
        direction = "left";
        go = true;
        canMoveAgain = false;

        velocity = -Vector3.right;
    } 
    else if (Input.GetKeyDown(KeyCode.RightArrow) && canMoveAgain)
    {
        direction = "right";
        go = true;
        canMoveAgain = false;
        velocity = Vector3.right;
    }

    if(go)
    {
        transform.position += velocity;
    }    
}

请注意,目前您的代码也依赖于帧速率。您可能更愿意使用

public float moveSpeed;

...

transform.position += velocity * moveSpeed * Time.deltaTime;

对于 direction 我宁愿推荐 enum 喜欢

private enum MoveDirection
{
    None,
    Up,
    Down,
    Left,
    Right
}

并使用它,例如喜欢

direction = MoveDirection.Up;

if(direction == MoveDirection.Up)

这比比较字符串更有效。


注意:在智能手机上打字,因此不提供保修,但我希望这个想法能得到理解

首先。不要关闭 Unity。 你有两件事可以尝试做。

  • 幸运的是,当您按 运行 时,您的代码有备份。 它位于 Temp 文件夹中。如果您再次按 运行,Temp 文件夹将被替换。将项目复制到安全的地方。

  • 附加调试器,这可以是 Visual Studio 或 MonoDevelop。一旦它们连接到 Unity,只需单击暂停。您可以随意保存您的项目。

我希望你在为时已晚之前找到这个答案。