Unity在播放时崩溃,很可能是无限的While循环,但无法定位问题 [英] Unity Crashing on Play, most likely infinite While loop, but cannot locate issue

查看:208
本文介绍了Unity在播放时崩溃,很可能是无限的While循环,但无法定位问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

感谢您的阅读.

我目前正在使用C#在Unity中构建一个小型存储卡游戏.我已经完成了代码的主要部分,但是当我在某个场景上按下播放按钮时,Unity冻结了. 我相信这是由于无限的While循环引起的,但我找不到问题.任何人都可以提供任何帮助,我将不胜感激.我将在下面保留我的代码.提前致谢.

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using UnityEngine;

public class Pairs : MonoBehaviour {

    public Sprite[] face; //array of card faces
    public Sprite back;
    public GameObject[] deck; //array of deck
    public Text pairsCount;


    private bool deckSetUp = false;
    private int pairsLeft = 13;


    // Update is called once per frame
    void Update () {
        if (!deckSetUp)
        {
            SetUpDeck();
        }
        if (Input.GetMouseButtonUp(0)) //detects left click
        {
            CheckDeck();
        }
    }//Update

    void SetUpDeck()
    {
        for (int ix = 0; ix < 2; ix++) 
        {
            for(int i = 1; i < 14; i++)//sets up card value (2-10 JQKA)
            {
                bool test = false;
                int val = 0;

                while (!test)
                {
                   val = Random.Range(0, deck.Length);
                   test = !(deck[val].GetComponent<Card>().SetUp);
                }//while

                //sets up cards

                deck[val].GetComponent<Card>().Number = i;
                deck[val].GetComponent<Card>().SetUp = true;

            }//nested for

        }//for

        foreach (GameObject crd in deck)
        {
            crd.GetComponent<Card>().setUpArt();
        }

        if (!deckSetUp)
        {
            deckSetUp = true;
        }
    }//SetUpDeck

    public Sprite getBack()
    {
        return back;
    }//getBack

    public Sprite getFace(int i)
    {
        return face[i - 1];
    }//getFace

    void CheckDeck()
    {
        List < int > crd = new List<int>();

        for(int i = 0; i < deck.Length; i++)
        {
            if(deck[i].GetComponent<Card>().State == 1)
            {
                crd.Add(i);
            }

        }

        if(crd.Count == 2)
        {
            CompareCards(crd);
        }
    }//CheckDeck

    void CompareCards(List<int> crd)
    {
        Card.NO_TURN = true; //stops cards turning

        int x = 0;

        if(deck[crd[0]].GetComponent<Card>().Number == 
  deck[crd[1]].GetComponent<Card>().Number)
        {
            x = 2;
            pairsLeft--;
            pairsCount.text = "PAIRS REMAINING: " + pairsLeft;

            if(pairsLeft == 0) // goes to home screen when game has been won
            {
                SceneManager.LoadScene("Home");
            }

        }

        for(int j = 0; j < crd.Count; j++)
        {
            deck[crd[j]].GetComponent<Card>().State = x;
            deck[crd[j]].GetComponent<Card>().PairCheck();

        }

    }//CompareCards
}

我认为问题出在while(!test)上,但我不知道为什么测试永远不会成真.

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;

public class Card : MonoBehaviour {

    public static bool NO_TURN = false; 

    [SerializeField]
    private int cardState; //state of card
    [SerializeField]
    private int cardNumber; //Card value (1-13)
    [SerializeField]
    private bool _setUp = false;

    private Sprite back; //card back (Green square)
    private Sprite face; //card face (1-10 JQKA)

    private GameObject pairsManager;

    void Begin()
    {
        cardState = 1; //cards face down
        pairsManager = GameObject.FindGameObjectWithTag("PairsManager"); 

    }

    public void setUpArt()
    {
        back = pairsManager.GetComponent<Pairs>().getBack();
        face = pairsManager.GetComponent<Pairs>().getFace(cardNumber);

        turnCard();//turns the card
    }

    public void turnCard() //handles turning of card
    {
        if (cardState == 0)
        {
            cardState = 1;
        }
        else if(cardState == 1)
        {
            cardState = 0;
        }
        if (cardState == 0 && !NO_TURN)
        {
            GetComponent<Image>().sprite = back; // shows card back
        }
        else if (cardState == 1 && !NO_TURN)
        {
            GetComponent<Image>().sprite = face; // shows card front
        }
    }

    //setters and getters

    public int Number
    {
        get {return cardNumber;}
        set { cardNumber = value;}
    }

    public int State
    {
        get { return cardState; }
        set { cardState = value; }
    }

    public bool SetUp
    {
        get { return _setUp; }
        set { _setUp = value; }
    }


    public void PairCheck() 
    {
        StartCoroutine(pause ());
    }

    IEnumerator pause()
    {
        yield return new WaitForSeconds(1); 
        if (cardState == 0)
        {
            GetComponent<Image>().sprite = back;
        }
        else if (cardState == 1)
        {
            GetComponent<Image>().sprite = face;
        }
    }
}

感谢您阅读,如果有帮助,我将发布指向github存储库的链接. github存储库

解决方案

您的卡座数组中至少有一张卡,该卡的_setUp设置为true会使它无限循环.

它进入无限循环的原因是因为它将所有可用的_setUp设置为true,并且它将继续查找设置为false_setUp,并且永远找不到.

/p>

之所以需要至少26个具有_setUpfalse的对象的原因是,在嵌套的for循环中,您循环了13次,然后又执行了两次,总共产生了26个循环.因此,您至少需要26个对象.

要确保它们全部为false,您可以做的是在进入for循环之前将它们全部设置为false.

for(int i = 0; i < deck.Length; i++)
{
    deck[i].GetComponent<Card>().SetUp = false;
} 

thanks for reading.

I'm currently building a small memory card game in Unity using C#. I have the main portion of code finished but when I press the play button on a certain scene Unity freezes. I believe it is due to an infinite While loop, but I can not find the issue. I would really appreciate any help anyone can offer. I will leave my code below. Thanks in advance.

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using UnityEngine;

public class Pairs : MonoBehaviour {

    public Sprite[] face; //array of card faces
    public Sprite back;
    public GameObject[] deck; //array of deck
    public Text pairsCount;


    private bool deckSetUp = false;
    private int pairsLeft = 13;


    // Update is called once per frame
    void Update () {
        if (!deckSetUp)
        {
            SetUpDeck();
        }
        if (Input.GetMouseButtonUp(0)) //detects left click
        {
            CheckDeck();
        }
    }//Update

    void SetUpDeck()
    {
        for (int ix = 0; ix < 2; ix++) 
        {
            for(int i = 1; i < 14; i++)//sets up card value (2-10 JQKA)
            {
                bool test = false;
                int val = 0;

                while (!test)
                {
                   val = Random.Range(0, deck.Length);
                   test = !(deck[val].GetComponent<Card>().SetUp);
                }//while

                //sets up cards

                deck[val].GetComponent<Card>().Number = i;
                deck[val].GetComponent<Card>().SetUp = true;

            }//nested for

        }//for

        foreach (GameObject crd in deck)
        {
            crd.GetComponent<Card>().setUpArt();
        }

        if (!deckSetUp)
        {
            deckSetUp = true;
        }
    }//SetUpDeck

    public Sprite getBack()
    {
        return back;
    }//getBack

    public Sprite getFace(int i)
    {
        return face[i - 1];
    }//getFace

    void CheckDeck()
    {
        List < int > crd = new List<int>();

        for(int i = 0; i < deck.Length; i++)
        {
            if(deck[i].GetComponent<Card>().State == 1)
            {
                crd.Add(i);
            }

        }

        if(crd.Count == 2)
        {
            CompareCards(crd);
        }
    }//CheckDeck

    void CompareCards(List<int> crd)
    {
        Card.NO_TURN = true; //stops cards turning

        int x = 0;

        if(deck[crd[0]].GetComponent<Card>().Number == 
  deck[crd[1]].GetComponent<Card>().Number)
        {
            x = 2;
            pairsLeft--;
            pairsCount.text = "PAIRS REMAINING: " + pairsLeft;

            if(pairsLeft == 0) // goes to home screen when game has been won
            {
                SceneManager.LoadScene("Home");
            }

        }

        for(int j = 0; j < crd.Count; j++)
        {
            deck[crd[j]].GetComponent<Card>().State = x;
            deck[crd[j]].GetComponent<Card>().PairCheck();

        }

    }//CompareCards
}

I believe the issue lies in the while(!test) but i do not know why test never become true.

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;

public class Card : MonoBehaviour {

    public static bool NO_TURN = false; 

    [SerializeField]
    private int cardState; //state of card
    [SerializeField]
    private int cardNumber; //Card value (1-13)
    [SerializeField]
    private bool _setUp = false;

    private Sprite back; //card back (Green square)
    private Sprite face; //card face (1-10 JQKA)

    private GameObject pairsManager;

    void Begin()
    {
        cardState = 1; //cards face down
        pairsManager = GameObject.FindGameObjectWithTag("PairsManager"); 

    }

    public void setUpArt()
    {
        back = pairsManager.GetComponent<Pairs>().getBack();
        face = pairsManager.GetComponent<Pairs>().getFace(cardNumber);

        turnCard();//turns the card
    }

    public void turnCard() //handles turning of card
    {
        if (cardState == 0)
        {
            cardState = 1;
        }
        else if(cardState == 1)
        {
            cardState = 0;
        }
        if (cardState == 0 && !NO_TURN)
        {
            GetComponent<Image>().sprite = back; // shows card back
        }
        else if (cardState == 1 && !NO_TURN)
        {
            GetComponent<Image>().sprite = face; // shows card front
        }
    }

    //setters and getters

    public int Number
    {
        get {return cardNumber;}
        set { cardNumber = value;}
    }

    public int State
    {
        get { return cardState; }
        set { cardState = value; }
    }

    public bool SetUp
    {
        get { return _setUp; }
        set { _setUp = value; }
    }


    public void PairCheck() 
    {
        StartCoroutine(pause ());
    }

    IEnumerator pause()
    {
        yield return new WaitForSeconds(1); 
        if (cardState == 0)
        {
            GetComponent<Image>().sprite = back;
        }
        else if (cardState == 1)
        {
            GetComponent<Image>().sprite = face;
        }
    }
}

Thank you for reading, I will post a link to the github repository if that helps. github repository

解决方案

Your deck array has at least one card in it that has _setUp set to true which would make it go in a infinite loop.

The reason it goes in a infinite loop is because it will have set all available _setUp to true and it would keep looking for _setUp that are set to false and it will never find any.

The reason you need at least 26 object that have _setUp to false is because in the nested for loop you loop 13 times and then you do that twice which gives a total of 26 loops. So you need at least 26 objects.

What you can do to make sure that they're all false is to set them all to false before entering the for loop

for(int i = 0; i < deck.Length; i++)
{
    deck[i].GetComponent<Card>().SetUp = false;
} 

这篇关于Unity在播放时崩溃,很可能是无限的While循环,但无法定位问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆