Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by RKM_91 · Apr 10, 2015 at 04:09 PM · c#guirandomunity 4.6

How to make questions & answers random in my script C#?

Hello Unity Answers,

I want to make my questions and answers random because at the moment the question is the same one when the player collides into the cube and the answers are in the same place as well.

Is there away to make it change randomly upon collision with a cube.

So for example, if the player runs out of time and is sent back to the start, I would like a new question to appear on screen, not "What year did Ebola begin?"

Also the answer is 1976, which is set in the top left button, can I place this somewhere else?

Any ideas/help/suggestions would be much appreciated.

alt text

 using System;
 using System.Collections.Generic;
 using UnityEngine;
 using System.Collections;
 using UnityEngine.UI;
 
 public class Question1 : MonoBehaviour {
     
     private Rect windowRect = new Rect (500, 100, 400, 200); //Window size
     public bool question1;
     private int count;
     public Text countText;
 
     private bool showTimer = true;
     private float Timer = 10f;
 
     
     void start()
     {
         count = 0;
         SetCountText ();
     }
 
 
     void FixedUpdate(){
         if (showTimer == true) {
             Timer -= Time.deltaTime;
         }
 
         if (Timer <= 0f) {
             showTimer = false;
             Timer = 10f;
             Destroy (this.gameObject);
             Application.LoadLevel (Application.loadedLevel);
 
         }
     }
 
     
     void OnGUI(){
         {
             windowRect = GUI.Window (0, windowRect, WindowFunction, "Ebola Quiz Island"); //window on screen 
         }
     }
 
 
     void WindowFunction (int windowID) 
     {
         // Draw any Controls inside the window here
 
         GUI.Label (new Rect (30, 25, 200, 50), " What year did Ebola begin?"); // Question
         
         if (GUI.Button (new Rect (20, 100, 100, 30), "1976")) // Correct Answer
         {
             Destroy (this.gameObject);
             count = count + 1;
             SetCountText ();
         } 
 
         if (GUI.Button (new Rect (280, 100, 100, 30), "1986")) //Wrong answer  
         {
             Destroy (this.gameObject);
             Application.LoadLevel(Application.loadedLevel);
         }
 
         if (GUI.Button (new Rect (20, 150, 100, 30), "1996")) // wrong answer
         {
             Destroy (this.gameObject);
             Application.LoadLevel(Application.loadedLevel);
         }
 
         if (GUI.Button (new Rect (280, 150, 100, 30), "1966")) // wrong answer
         {
             Destroy (this.gameObject);
             Application.LoadLevel(Application.loadedLevel);
         }
 
         if (showTimer == true) 
         {
             GUI.Label (new Rect (300, 25, 200, 50), "Timer: " + Timer.ToString ("F0"));
         }
 
 
     }
 
     void SetCountText()
         {
             countText.text = "Score: " + count.ToString ();
         }
 
 
 }
 

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by equus_ligneus · Apr 10, 2015 at 11:53 PM

The easiest way to implement this is to create instances of a question class (preferrably not in a scene but in the project folder) which hold the question and the possible answers and let them handle randomizing the button positions.

 using UnityEngine;
 using System.Collections.Generic;
 
 // A Question
 public class MyQuestion : ScriptableObject {
 
     // the question
     public string question;
 
     // the different answers (answer[0] is right answer by default)
     public string[] answers;
 
     // the order, in which answers are displayed
     private int[] m_order;
 
     //This does not work outside the Editor
 #if UNITY_EDITOR
     // Create Questions from Folder Context Menu
     [UnityEditor.MenuItem("Assets/Create/Question")]
     public static void CreateQuestion()
     {
         string resourcePath = "Assets/Resources/Questions";
 
         // makes sure you have a directory to save your question to.
         if (!System.IO.Directory.Exists(Application.dataPath + "/Resources"))
         {
             UnityEditor.AssetDatabase.CreateFolder("Assets", "Resources");
         }
         if (!System.IO.Directory.Exists(Application.dataPath + "/Resources/Questions"))
         {
             UnityEditor.AssetDatabase.CreateFolder("Assets/Resources", "Questions");
         }
 
         // create question
         MyQuestion myQuestion = CreateInstance<MyQuestion>();
         
         // name question
         int questions = UnityEditor.AssetDatabase.FindAssets("", new string[1]{resourcePath}).Length;
         myQuestion.name = "Question_" + questions;
 
         // save question to project folder
         UnityEditor.AssetDatabase.CreateAsset(myQuestion, resourcePath + "/" + myQuestion.name + ".asset");
     }
 #endif
 
     public void OnEnable()
     {
         if (question == null)
         {
             question = "";
         }
         if (answers == null)
         {
             answers = new string[4] { "", "", "", "" };
         }
         // Prevents exceptions in OnGUI if you forget to call RandomizeAnswers() 
         m_order = new int[answers.Length];
         for (int i = 0; i < m_order.Length; ++i)
         {
             m_order[i] = i;
         }
     }
 
     // Randomizes the order in which answers are presented
     public void RandomizeAnswers()
     {
         System.Random random = new System.Random();
         List<int> order = new List<int>();
         
         // get indices
         for (int i = 0; i < answers.Length; ++i)
         {
             order.Add(i);
         }
 
         m_order = new int[answers.Length];
         int index = 0;
 
         // shuffle indices
         while (order.Count > 0)
         {
             int index2 = random.Next(order.Count);
             m_order[index] = order[index2];
             order.RemoveAt(index2);
             ++index;
         }
     }
 
     /* Your Question display function
      * returns true (right answer), false (wrong answer) or null (nothing chosen) */
     public bool? ShowQuestion(Rect _area)
     {
         // bool that can be true, false or null. ? makes any struct nullable
         bool? result = null;
 
         // just a simple layout
         GUILayout.BeginArea(_area);
 
         // display question
         GUILayout.Label(question);
 
         for (int i = 0; i < answers.Length; ++i)
         {
             // display buttons in random order
             if (GUILayout.Button(answers[m_order[i]]))
             {
                 if (m_order[i] == 0)    // right choice
                 {
                     result = true;
                 }
                 else                    // wrong choice
                 {
                     result = false;
                 }
             }
         }
         GUILayout.EndArea();
 
         return result;
     }
 
 }

(You can save instances of classes that inherit from ScriptableObject as assets in in your project)

Now to randomize the questions themselves, one way to go is use a central question pool that holds all questions and ask for new question every time the question trigger is entered.

 using UnityEngine;
 using System.Collections;
 
 // Singleton for managing the question pool
 public class MyQuestionPool {
 
     // static instance
     private static MyQuestionPool m_questionPool = null;
 
     // all questions
     private MyQuestion[] m_questions = null;
 
     private System.Random m_random = null;
 
 
     private MyQuestionPool()
     {
         m_random = new System.Random();
         InitQuestions();
     }
 
     // Loads questions
     private void InitQuestions()
     {
         /* Resources.Load looks inside the Assets/Resources-folder
          * full path is Assets/Resources/Questions */
         m_questions = Resources.LoadAll<MyQuestion>("Questions");
     }
 
     // Gets the question pool
     public static MyQuestionPool Instance
     {
         get
         {
             if (m_questionPool == null)
             {
                 m_questionPool = new MyQuestionPool();
             }
             return m_questionPool;
         }
     }
 
     // Gets a random question
     public MyQuestion GetQuestion()
     {
         if (m_questions != null && m_questions.Length > 0)
         {
             int index = m_random.Next(m_questions.Length);
             m_questions[index].RandomizeAnswers();
             return m_questions[index];
         }
 
         return null;
     }
 }
 

At last, the trigger:

 using UnityEngine;
 using System.Collections;
 
 // A question trigger
 public class MyQuestionTrigger : MonoBehaviour {
 
     // current question
     private MyQuestion m_question = null;
 
     public void OnGUI()
     {
         // Display Question
         if (m_question)
         {
             bool? result = m_question.ShowQuestion(new Rect(Screen.width / 2 - 200, Screen.height / 2 - 200, 400, 400));
 
             if (result == null)
             {
                 // no answer, wait...
                 return;
             }
             else if (result == true)
             {
                 // right answer given
             }
             else
             {
                 // wrong answer given
             }
 
             // discard question
             m_question = null;
         }
     }
 
     public void OnTriggerEnter(Collider _col)
     {
         // Get Question
         m_question = MyQuestionPool.Instance.GetQuestion();
     }
 }


With this you can add questions until you run out of RAM, Array-Indices or ideas for new questions. You can edit them in your inspector. Just do not delete questions or it will screw with the way new questions are named.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image equus_ligneus · Apr 10, 2015 at 11:57 PM 0
Share

I should add that since $$anonymous$$yQuestionPool is not a $$anonymous$$onoBehaviour it will not be destroyed during level loads.

avatar image khidz93 · Sep 05, 2015 at 01:11 PM -1
Share

Hi. im currently working on a similar project. and still a newbie. so may i ask how do u implement these scripts?

avatar image equus_ligneus · Sep 08, 2015 at 02:56 PM 0
Share

Out of the three scripts, only $$anonymous$$yQuestionTrigger needs to be put on a GameObject. An instance of $$anonymous$$yQuestion can be created like a new script (right-clicking in the Project-window >"Question").

At runtime, when you run into a $$anonymous$$yQuestionTrigger, the trigger asks a static $$anonymous$$yQuestionPool instance to get a question. If the $$anonymous$$yQuestionPool instance has not been created, it will create itself and load all $$anonymous$$yQuestions from the Resources-folder. Then it will return a random question, which the trigger will display until a) the question has been answered (right or wrong does not matter) or b) the player runs into the same trigger again. I hope I could help.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

20 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Loading Game Crash 1 Answer

Multiplayer Hiding Layer just for Local Player 0 Answers

Beginner trying to set up random variable for game + and then some. 2 Answers

Random Generator Instantiate Tiles C# = PLEASE HELP = 0 Answers

How to instantiate (MonoBehaviour) script multiple times and call void? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges