Reputation: 19
I'm an educational researcher developing a game for my doctoral program. I'm learning on the go with tutorials and forums.
I have this scene with quiz panels (i.e., 4 buttons - 1 correct answer and 3 wrong ones)
I would love to know how to provide the feedback hints in order regardless of which wrong button was clicked.
These are some pics of the panel and the code I currently have.
Question Panel Image with canvas elements
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PPLQuizManager : MonoBehaviour
{
public GameObject HNSCanvas;
[Header("PPL Left Panel")]
public GameObject PPLLeftPanel;
public RectTransform PPLParentLeftPanel;
public GameObject PPLTextBox;
public GameObject PPLContinue;
public GameObject PPLReturn;
//Pictures that illustrate the tutor's reaction
public List<Sprite> questionimages;
public List<Sprite> HintImages;
public List<Sprite> CorrectImages;
public GameObject PPLStringImages;
[Header("PPL Right Panel")]
public GameObject PPLRightPanel;
public GameObject PPLChoice1;
public GameObject PPLChoice2;
public GameObject PPLChoice3;
public GameObject PPLChoice4;
public int PPLChoiceMade;
[Header("PPL Bottom Panel")]
public GameObject PPLBottomPanel;
public GameObject PPLHint1TextBox;
public GameObject PPLHint2TextBox;
public GameObject PPLHint3TextBox;
public GameObject PPLWinTextBox;
public GameObject PPLHintPic;
public GameObject PPLBadge;
public GameObject PPLMedalPic;
[Header("PPL Center Panel")]
public GameObject PPLCenterPanel;
public GameObject PPLHintPic1;
public GameObject PPLHintPic2;
public GameObject PPLHintPic3;
public GameObject PPLWinPic;
public void PPLChoiceOption1()
{
PPLChoice1.GetComponent<Button>().interactable = false;
PPLTextBox.GetComponent<Text>().text = "Read the hint. Try again.";
showRandomHintImage();
PPLChoiceMade = 1;
}
public void PPLChoiceOption2()
{
PPLChoice2.GetComponent<Button>().interactable = false;
PPLTextBox.GetComponent<Text>().text = "Congratulations!";
showRandomCorrectImage();
PPLChoiceMade = 2;
}
public void PPLChoiceOption3()
{
PPLChoice3.GetComponent<Button>().interactable = false;
PPLTextBox.GetComponent<Text>().text = "Here's a hint!";
showRandomHintImage();
PPLChoiceMade = 3;
}
public void PPLChoiceOption4()
{
PPLChoice4.GetComponent<Button>().interactable = false;
PPLTextBox.GetComponent<Text>().text = "Hint time. Go for it!";
showRandomHintImage();
PPLChoiceMade = 4;
}
public void showRandomQuestionImage()
{
int count = questionimages.Count;
int index = Random.Range(0, count);
Image image1 = PPLStringImages.GetComponent<Image>();
image1.sprite = questionimages[index];
}
public void showRandomCorrectImage()
{
int count = CorrectImages.Count;
int index = Random.Range(0, count);
Image image2 = PPLStringImages.GetComponent<Image>();
image2.sprite = CorrectImages[index];
}
public void showRandomHintImage()
{
int count = HintImages.Count;
int index = Random.Range(0, count);
Image image3 = PPLStringImages.GetComponent<Image>();
image3.sprite = HintImages[index];
}
private void Start()
{
showRandomQuestionImage();
}
// Update is called once per frame
void Update()
{
//check the rest of this post
}
}
What I did to have it functional is to assign each hint to a certain wrong answer button. But this method will not be interesting for my research, especially because the 3rd hint is practically an answer giveaway. So, if a student clicks on a wrong answer that I manually assigned the 3rd hint to be in, they will get the answer on a silver platter, and my data be crappy. = (
Just to remember: I need to display hints 1, 2, and 3 in order regardless of which wrong button the students clicks.
EXTRA REQUEST = ) : Is there a way to manage these panel game objects in a more economical and effective way?
// Update is called once per frame
void Update()
{
//PPL buttons and answer management
if (PPLChoiceMade == 1)
{
PPLCenterPanel.SetActive(true);
PPLHintPic1.SetActive(true);
PPLHintPic2.SetActive(false);
PPLHintPic3.SetActive(false);
PPLHint1TextBox.SetActive(true);
PPLHint2TextBox.SetActive(false);
PPLHint3TextBox.SetActive(false);
}
if (PPLChoiceMade == 2)
{
PPLCenterPanel.SetActive(true);
PPLHintPic1.SetActive(false);
PPLHintPic2.SetActive(false);
PPLHintPic3.SetActive(false);
PPLWinPic.SetActive(true);
PPLChoice1.SetActive(false);
PPLChoice2.SetActive(true);
PPLChoice3.SetActive(false);
PPLChoice4.SetActive(false);
PPLContinue.SetActive(true);
PPLReturn.SetActive(false);
PPLWinTextBox.SetActive(true);
PPLHint1TextBox.SetActive(false);
PPLHint2TextBox.SetActive(false);
PPLHint3TextBox.SetActive(false);
PPLBadge.SetActive(true);
PPLMedalPic.SetActive(true);
}
if (PPLChoiceMade == 3)
{
PPLCenterPanel.SetActive(true);
PPLHintPic1.SetActive(false);
PPLHintPic2.SetActive(true);
PPLHintPic3.SetActive(false);
PPLHint1TextBox.SetActive(false);
PPLHint2TextBox.SetActive(true);
PPLHint3TextBox.SetActive(false);
}
if (PPLChoiceMade == 4)
{
PPLCenterPanel.SetActive(true);
PPLHintPic1.SetActive(false);
PPLHintPic2.SetActive(false);
PPLHintPic3.SetActive(true);
PPLHint1TextBox.SetActive(false);
PPLHint2TextBox.SetActive(false);
PPLHint3TextBox.SetActive(true);
}
Any help will be highly appreciated!! (especially because I've already burned tons of neurons trying to figure it out myself... Lol!)
Upvotes: 1
Views: 72
Reputation: 447
To answer your extra request make a parent container object and place all your containers within that parent and then loop through them in this fashion
public GameObject hintBoxContainer;
private List<GameObject> hintBoxes = new List<GameObject>();
private void Start(){
for(int i =0; i < hintBoxContainer.transform.childCount; i++){
hintBoxes.Add(hintBoxContainer.transform.getChild(i).gameObject);
}
}
private void Update(){
if(PPLChoiceMade == 1){
//Since we know the first hintbox is at the index of 0
for(int i =0; i < hintBoxes.Count; i++){
if(i == 0){
hintBox[i].SetActive(true);
}else{
hintBox[i].SetActive(false);
}
}
}
}
As an extra note
You should create a separate function for initializing the list so you do not crowd your start function as well as break down whats inside the update into functions so you keep your code clean and modular. Remember to take some time to optimize and keep optimization and modular design techniques in mind I have had many projects fall apart in my early days by designing my systems fast instead of "right" :)
Upvotes: 1
Reputation: 1074
Let's take a look at this in pseudocode
if student clicks wrong
Increment the number of times they have given wrong answers by 1
What number of incorrect answers have they given?
if 1 then display hint 1
if 2 then display hint 2
if 3 then display hint 3
Allow them to answer again
You'll need a few things given this pseudcode:
A counter to keep track of the number of wrong answers given
public int numberOfWrongAnswers = 0;
An array (or list) of hints in order to be given
public string[] hints;
An array containing references to your buttons
public GameObject[] answerButtons;
A generic method to determine which button was pressed
public void PPLChoiceOption(int selection)
From this, I would make your method like this
public void PPLChoiceOption(int selection)
{
buttons[selection].GetComponent<Button>().interactable = false;
PPLTextBox.GetComponent<Text>().text = hints[numberOfWrongAnswers - 1];
showRandomHintImage();
PPLChoiceMade = selection;
}
Make sure that you change the reference on your buttons to point to this method and put a 0 in the parameter for the first button, 1 for the next, etc.
Upvotes: 1