How do I fix this loop causing the program to freeze?

I’ve been attempting to create a system that selects a random string from one of several array lists based on which lists I currently have set to be available, but have run into several issues.

The way it’s meant to work is that my code selects a random number from a range, based on how many lists I have, then, through a series of if statements, tracks down the relevant list and determines whether or not its set to be available. If it is, the code selects a random string from that array and prints it to a text box in my scene. If it isn’t, the code cycles through the remaining ifs, before looping back to the beginning through a while loop (formerly a for loop, but i’ve been trying different options whilst attempting to fix this), where the code “rerolls” the random number and tries again until a match happens, at which point the loop is broken until the function containing all of this is called again.

I’m running into a problem, though. Previously, before I implemented the loop (which was part of an overhaul to make my code more efficient and hundreds of lines shorter), the string call level was working fine, as was the selection of which lists were available (there were a few glitches, but I think I fixed them). Now, I can’t even get to the string level because Unity freezes the moment I press the in-scene button that triggers the entire selection sequence.

Through research, i’ve learned this is probably being caused by the loop repeating forever without an exit point, but the way i’ve set it up, at least to me, seems like there should be one, as its meant to repeat until the number it generates matches one of the selected lists.

I’m out of ideas, basically, and am hoping that a fresh perspective will be able to see something obvious that my tired brain is skimming over.

    public bool checkList1;
    public bool checkList2;
    public bool checkList3;
    public bool checkList4;
    public bool checkList5;
    public bool checkList6;

    public int findArray;
    public int i;

    public string resultText;
	public Text resultOutput;

	/*List1*/ public List<string> rand1 = new List<string>();
    /*List2*/ public List<string> rand2 = new List<string>();
    /*List3*/ public List<string> rand3 = new List<string>();
    /*List4*/ public List<string> rand4 = new List<string>();
    /*List5*/ public List<string> rand8 = new List<string>();
    /*List6*/ public List<string> rand16 = new List<string>();

    public void Start () {
        checkList1 = false;
		checkList2 = false;
        checkList3 = false;
		checkList4 = false;
        checkList5 = false;
        checkList6 = false;

        findArray = -1;
        i = 0;

		resultText = "";
		nameButton.onClick.AddListener (TaskOnClick);
	}

	public void Update () {
		if (togList1.isOn) {
			checkList1 = true;
		}else{
			checkList1 = false;
		}
		if (togList2.isOn) {
			checkList2 = true;
		}else{
			checkList2 = false;
		}
        if (togList3.isOn)
        {
            checkList3 = true;
        }else{
            checkList3 = false;
        }
		if (togList4.isOn) {
			checkList4 = true;
		}else{
			checkList4 = false;
		}
        if (togList5.isOn) {
            checkList5 = true;
        }else{
            checkList5 = false;
        }
        if (togList5.isOn) {
            checkList5 = true;
        }else{
            checkList5 = false;
        }
	}

    public void TaskOnClick()
    {
        while (i == 0)
        {
            findArray = Random.Range(1, 17);
            Debug.Log(findArray);

            if (findArray == 1 && checkList1 == true)
            {
                Debug.Log("1");
                i++;
                CallRand1();
            }
            else if (findArray == 2 && checkList2 == true)
            {
                Debug.Log("2");
                i++;
                CallRand2();
            }
            else if (findArray == 3 && checkList3 == true)
            {
                Debug.Log("3");
                i++;
                CallRand3();
            }
            else if (findArray == 4 && checkList4 == true)
            {
                Debug.Log("4");
                i++;
                CallRand4();
            }
            else if (findArray == 8 && checkList5 == true)
            {
                Debug.Log("8");
                i++;
                CallRand8();
            }
            else if (findArray == 16 && checkList6 == true)
            {
                Debug.Log("16");
                i++;
                CallRand16();
            }
            else if (findArray >= 5 && findArray <= 7)
            {
                Debug.Log("UNUSED");
            }
            else if (findArray >= 9 && findArray <= 15)
            {
                Debug.Log("UNUSED");
            }
        }
    }

How have you ended up with such script? Below is a suggestion of simplification, but you might not be able to apply to your code since you haven’t provided your full script and you did not explain what it was supposed to do (except selecting random things)

[System.Serializable]
public class MyClass // Rename this class
{
    public List<string> Rand = new List<string>();
    public Toggle Toggle;

    public string Foo()
    {
        // Do the logic of your CallRandX method
    }
}

public class YourClassName : MonoBehaviour
{
    public string resultText;
    public Text resultOutput;

    [SerializeField]
    private MyClass[] MyClasses;

    private void Start ()
    {
        resultText = "";
        nameButton.onClick.AddListener(TaskOnClick);
    }

    public void TaskOnClick()
    {
        MyClass[] enabledClasses = System.Find( MyClasses, obj => obj.Toggle.isOn);
        if(enabledClasses.Length == 0)
             return;
        int index = Random.Range(0, enabledClasses.Length);
        resultText = enabledClasses[index].Foo();
        resultOutput.text = resultText;
    }
}

In your update, if TogListX.isOn is false, (i dont see it being set to true anywhere), it will set checkListX =false always. never to true.
If that’s the case, then in your TaskOnClick(), checklistX will never be true, so even if you do get a good findArray number (4 for example), checklist4 will be false, so you wont enter into the if statement, therefore i++ is never called, meaning i is still 0, so your while(i==0) becomes an infinite loop.

In your update, if TogListX.isOn is false, (i dont see it being set to true anywhere), it will set checkListX =false always. never to true.
If that’s the case, then in your TaskOnClick(), checklistX will never be true, so even if you do get a good findArray number (4 for example), checklist4 will be false, so you wont enter into the if statement, therefore i++ is never called, meaning i is still 0, so your while(i==0) becomes an infinite loop.