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;
}
}
}
}
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.
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 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:
Show user question at index 0
awaiting answerâŚ
User answers.
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
show question at new index (or the new thing I know not what you want ;)).
Sorry, Iâm not well-versed with those OnGUI things.
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):
Pretty much what I said, but much nicer instructions.
@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();
}
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.