Iteration

Hey, I am looking to iterate through a list that contains statements for the user to respond to and the user must click one of the response buttons before the next item in the list is displayed. In my code I have attempted to use foreach but I cannot get this to work. I have attached the script for you to run/look at.

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

public class IQuestions : MonoBehaviour
{
    public string[] QList = new string[3] { "I am Stressed", "I am overworked", "I am tired" };
    private int[] MoodVal = new int[3];
    private Rect windowRect = new Rect(0, 0, Screen.width, Screen.height);
    private int itemCount = 0;
    private bool Answer = true;
    public void OnGUI()
    {
        GUI.Window(0, windowRect, WindowFunction, "Questions");
    }
    public void WindowFunction(int windowID)
    {
        foreach(var item in QList)
        {
            GUI.Label(new Rect(Screen.width / 2, 3 * Screen.height / 5, Screen.width / 2, Screen.height / 8), (QList[itemCount]));
            Debug.Log(QList[itemCount]);
            if (GUI.Button(new Rect(Screen.width / 4, 4 * Screen.height / 5, Screen.width / 2, Screen.height / 8), "Great"))
            {
                Debug.Log("A2");
                MoodVal[itemCount] = 4;
                Debug.Log(MoodVal);
                itemCount = +1;
            }
            else if (GUI.Button(new Rect(Screen.width / 4, 3 * Screen.height / 5, Screen.width / 2, Screen.height / 8), "Good"))
            {
                Debug.Log("A3");
                MoodVal[itemCount] = 3;
                Debug.Log(MoodVal);
                itemCount = +1;
            }
            else if (GUI.Button(new Rect(Screen.width / 4, 2 * Screen.height / 5, Screen.width / 2, Screen.height / 8), "Bad"))
            {
                Debug.Log("A4");
                MoodVal[itemCount] = 2;
                Debug.Log(MoodVal);
                itemCount = +1;
            }
            else if (GUI.Button(new Rect(Screen.width / 4, 1 * Screen.height / 5, Screen.width / 2, Screen.height / 8), "Awful"))
            {
                Debug.Log("A5");
                MoodVal[itemCount] = 1;
                Debug.Log(MoodVal);
                itemCount = +1;
            }
        }
    }
}

Many thanks

3342481–261055–IQuestions.cs (1.74 KB)

Most people prefer you post the code in the forums using code tags Using code tags properly

Chances are you don’t want a loop. You probably just want a variable to track what you should display, then display it, let the user pick, add one to the variable, then access your collection to display the next set or display your end message if the variable is == to the size of your collection.

The code you have above will all run pretty much all instantaneously, not what you want.

If you want your program to show question 1, wait for answer, show question 2, etc., somewhere you need to keep track of which question is being processed, and if the user has or has not yet responded.

You can do this with some clever booleans hooked up to Unity uGUI objects, or if you want to do it with good old GUI, you need to track the possible states that your question system can be in, advance variables through that state, etc.

Look into coroutines also, because that is another way to track time-sequenced state, essentially as a “where in the coroutine we’re executing right now” type of situation.

1 Like

How can it loop back without using a loop?

Post the code with code tags? Check @Brathnann 's for a link on how to do that.

@methos5k I think I’ve done it, is that what you mean?

Yep, looks right. Can’t you see it, too? lol :slight_smile:

Oh yeah I just needed to refresh the page XD

Okay… First off, you are using the old OnGUI system. You should try getting used to the newer (yet been here a while now) system :slight_smile: Things found in : Create → UI - > (stuff here)

So, all you need, in either system, is to display the question at whichever index you’re at. Then, offering your responses, when the user gives their answer, you can display the next one.
I think the notion of not needing to loop is, imagine this:

Steps:

  1. Show user question at index 0
  2. awaiting answer…
  3. User answers.
  4. now, you can add 1 to the index (verify you’re not out of range) ; maybe you want to go back to 0 if you are or do something else, who knows
  5. show question at new index (or the new thing I know not what you want ;)).

Does that make sense? :slight_smile:

So would I need to recall WindowFunction each time I want to change the question?

Sorry, I’m not well-versed with those OnGUI things. :slight_smile:
Hmm. I would say you don’t have to.
What I would do (well, if it were me I’d switch to the new UI system first off), but anyhow…
I would remove the loop.

I guess you’d also want to check if you’re “done” in the OnGUI call, and if so, no longer show the window…
You could try that.

Oh, btw your ‘itemCount’ is not going to be working as you might imagine. The way you’ve written it, you’re merely assigning 1 to it each time. You have to change that to (one of these):

itemCount++;
itemCount = itemCount + 1;
++itemCount;

Hope that helps :slight_smile:

Pretty much what I said, but much nicer instructions. :slight_smile:

@ozzwozz
Oh, and as @methos5k mentions, switch to the new UI system. Much easier to work with.

You don’t want a loop. You want a variable tracking where you should be in your collection of questions (QList it appears).

Something like this. Note I typed this up quick in the forum, excuse typos and take it as a guide.

int questionIndex = 0;

public void DisplayQuestion)(
{
    if(questionIndex < QList.Count)
    {
        //Assign question data to your gui
        questionText.Text = QList[questionIndex];
    }
    else
        //All questions asked, do something else
}

public void QuestionAnswered()
{
   //Do stuff related to right or wrong answer
    questionIndex++;
    DisplayQuestion();
}

For sure… :slight_smile:

Try to lean towards that new UI… lol and then if you’re not getting there, try harder. lol :slight_smile: :slight_smile:

Thanks for the help both of you! I will also look into the new UI stuff

Cool. You’re welcome. Enjoy your game :slight_smile:

Definitely try to use the new UI stuff. The GUI stuff, while awesome in its own immediate-mode regard, does not scale, is not necessarily performant, and is best relegated to writing debug stuff and editor scripts.

Another term for what you’re trying to do as far as sequencing behavior through particular discrete steps is called a “state machine.” The simplest state machine is just a numeric counter that advances linearly through separate behaviors, such as what @methos5k listed above in his “Steps” post. A more-complicated state machine might have different routes between different states, such as “going back to question X,” for instance.