Программа Unity перестала отвечать из-за бесконечного цикла while - PullRequest
0 голосов
/ 11 мая 2019

Здравствуйте, переполнение стека пользователей! Я создавал игру в единстве 2018.2.2f1. Все прошло отлично, но я неправильно определил порядок строк кода в программе ->, что вызвало появление бесконечного цикла. Я не знал, что это будет бесконечно, поэтому я запустил программу. Теперь мое окно единства недоступно для выбора, когда я нажимаю на значок, и когда я вхожу в окно, все заморожено. Я бы закрыл диспетчер задач через программу, но я не сохранил свои файлы и даже не могу сохранить проект. Есть ли способ сохранить проект, когда он находится в этом состоянии? Мое единство не рухнуло, оно просто замерзло. Вот мой ИСПРАВЛЕННЫЙ код 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";
        }
    }
}

Ответы [ 2 ]

2 голосов
/ 11 мая 2019

Вы делаете

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

, но go никогда не устанавливается в ложь внутри цикла .

OnCollisionEnter никогда не выполняется, поскольку while все еще выполняется => стоп-кадр.

, поскольку Update вызывается каждый кадр, в любом случае, вам лучше переместить эту часть в отдельный *Блок 1014 * после проверки входов.

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)

, что более эффективно, чем сравнение строк.


Примечание: напечатано на смартфоне, поэтому никаких гарантий, но я надеюсь, что идеястановится ясным

1 голос
/ 12 мая 2019

Прежде всего.Не выключайте компьютер.

Вы можете сделать несколько вещей.К счастью, у вашего кода есть резервная копия, когда вы нажимаете run.Он находится внутри папки Temp.Папка Temp будет заменена при повторном нажатии.Скопируйте весь свой проект в безопасное место.

Попробуйте проверить, есть ли в папке Temp правильная резервная копия.

У вас есть другой вариант.Присоединить отладчик это может быть либо Visual Studio, либо MonoDevelop.Как только они присоединены к Unity, просто нажмите Pause.И вы можете свободно сохранять свои вещи.

Я надеюсь, что вы найдете этот ответ, пока не стало слишком поздно.

...