Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Iteration

Discussion in 'Scripting' started by ozzwozz, Jan 4, 2018.

  1. ozzwozz

    ozzwozz

    Joined:
    Sep 15, 2015
    Posts:
    39
    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.
    Code (csharp):
    1.  
    2. using System;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6. using UnityEngine.SceneManagement;
    7.  
    8. public class IQuestions : MonoBehaviour
    9. {
    10.     public string[] QList = new string[3] { "I am Stressed", "I am overworked", "I am tired" };
    11.     private int[] MoodVal = new int[3];
    12.     private Rect windowRect = new Rect(0, 0, Screen.width, Screen.height);
    13.     private int itemCount = 0;
    14.     private bool Answer = true;
    15.     public void OnGUI()
    16.     {
    17.         GUI.Window(0, windowRect, WindowFunction, "Questions");
    18.     }
    19.     public void WindowFunction(int windowID)
    20.     {
    21.         foreach(var item in QList)
    22.         {
    23.             GUI.Label(new Rect(Screen.width / 2, 3 * Screen.height / 5, Screen.width / 2, Screen.height / 8), (QList[itemCount]));
    24.             Debug.Log(QList[itemCount]);
    25.             if (GUI.Button(new Rect(Screen.width / 4, 4 * Screen.height / 5, Screen.width / 2, Screen.height / 8), "Great"))
    26.             {
    27.                 Debug.Log("A2");
    28.                 MoodVal[itemCount] = 4;
    29.                 Debug.Log(MoodVal);
    30.                 itemCount = +1;
    31.             }
    32.             else if (GUI.Button(new Rect(Screen.width / 4, 3 * Screen.height / 5, Screen.width / 2, Screen.height / 8), "Good"))
    33.             {
    34.                 Debug.Log("A3");
    35.                 MoodVal[itemCount] = 3;
    36.                 Debug.Log(MoodVal);
    37.                 itemCount = +1;
    38.             }
    39.             else if (GUI.Button(new Rect(Screen.width / 4, 2 * Screen.height / 5, Screen.width / 2, Screen.height / 8), "Bad"))
    40.             {
    41.                 Debug.Log("A4");
    42.                 MoodVal[itemCount] = 2;
    43.                 Debug.Log(MoodVal);
    44.                 itemCount = +1;
    45.             }
    46.             else if (GUI.Button(new Rect(Screen.width / 4, 1 * Screen.height / 5, Screen.width / 2, Screen.height / 8), "Awful"))
    47.             {
    48.                 Debug.Log("A5");
    49.                 MoodVal[itemCount] = 1;
    50.                 Debug.Log(MoodVal);
    51.                 itemCount = +1;
    52.             }
    53.         }
    54.     }
    55. }
    56.  
    Many thanks
     

    Attached Files:

    Last edited: Jan 5, 2018
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,140
    Most people prefer you post the code in the forums using code tags https://forum.unity.com/threads/using-code-tags-properly.143875/

    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.
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,599
    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.
     
    whileBreak likes this.
  4. ozzwozz

    ozzwozz

    Joined:
    Sep 15, 2015
    Posts:
    39
    How can it loop back without using a loop?
     
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Post the code with code tags? Check @Brathnann 's for a link on how to do that.
     
  6. ozzwozz

    ozzwozz

    Joined:
    Sep 15, 2015
    Posts:
    39
    @methos5k I think I've done it, is that what you mean?
     
  7. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Yep, looks right. Can't you see it, too? lol :)
     
  8. ozzwozz

    ozzwozz

    Joined:
    Sep 15, 2015
    Posts:
    39
    Oh yeah I just needed to refresh the page XD
     
  9. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    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:
    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? :)
     
  10. ozzwozz

    ozzwozz

    Joined:
    Sep 15, 2015
    Posts:
    39
    So would I need to recall WindowFunction each time I want to change the question?
     
  11. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    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):
    Code (csharp):
    1.  
    2. itemCount++;
    3. itemCount = itemCount + 1;
    4. ++itemCount;
    5.  
    Hope that helps :)
     
  12. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,140
    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.
    Code (CSharp):
    1. int questionIndex = 0;
    2.  
    3. public void DisplayQuestion)(
    4. {
    5.     if(questionIndex < QList.Count)
    6.     {
    7.         //Assign question data to your gui
    8.         questionText.Text = QList[questionIndex];
    9.     }
    10.     else
    11.         //All questions asked, do something else
    12. }
    13.  
    14. public void QuestionAnswered()
    15. {
    16.    //Do stuff related to right or wrong answer
    17.     questionIndex++;
    18.     DisplayQuestion();
    19. }
     
  13. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    For sure.. :)

    Try to lean towards that new UI.. lol and then if you're not getting there, try harder. lol :) :)
     
  14. ozzwozz

    ozzwozz

    Joined:
    Sep 15, 2015
    Posts:
    39
    Thanks for the help both of you! I will also look into the new UI stuff
     
  15. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Cool. You're welcome. Enjoy your game :)
     
  16. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,599
    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.
     
    Last edited: Jan 5, 2018