I have been working on a customization system that allows a player to customize their skin color and particle trail of their character. I have the system working and am now attempting to save the data through JsonUtility and then load it. I plan on saving the data with the play button then transitioning to a new scene and having it load at start() of the new scene. But, for testing I have been using a load button as it should still work...but it doesn't.
My current SaveSystem script is supposedly working since the DebugLog "Save file created" for saving files appears when the button is pressed. But, when pressing the load button nothing changes yet the DebugLog "Save file found and loaded" still appears. I am kinda lost as to where to go and how to load the data into the Customization script since I am still new to C# Json and serializing in general.
Here are my 3 scripts:
SaveSystem Script
using UnityEngine;
using System.IO;
public static class SaveSystem
using UnityEngine;
using System.IO;
public static class SaveSystem
{
public static string directory = "/saveData";
public static string fileName = "MyData.txt";
public static void SavePlayer(Customization CurrentCustomization)
{
string dir = Application.persistentDataPath + directory;
if(!Directory.Exists(dir))
Directory.CreateDirectory(dir);
Debug.Log("Save file created");
string json = JsonUtility.ToJson(CurrentCustomization);
File.WriteAllText(dir + fileName, json);
}
public static Customization LoadPlayer()
{
string fullPath = Application.persistentDataPath + directory + fileName;
Customization CurrentCustomization = new Customization();
if(File.Exists(fullPath))
{
string json = File.ReadAllText(fullPath);
CurrentCustomization = JsonUtility.FromJson<Customization>(json);
Debug.Log("Save file found and loaded");
}
else
{
Debug.Log("Save file does not exist");
}
return CurrentCustomization;
}
}
CharacterCustomizaiton Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class CharacterCustomization : MonoBehaviour
{
public List<Customization> Customizations;
public int currentCustomizationIndex;
public Customization CurrentCustomization {get; private set;}
[SerializeField] private TextMeshProUGUI bodyColorText;
[SerializeField] private TextMeshProUGUI trailText;
public void Save()
{
SaveSystem.SavePlayer(CurrentCustomization);
}
public void Load()
{
CurrentCustomization = SaveSystem.LoadPlayer();
}
void Awake()
{
foreach(var customization in Customizations)
{
customization.UpdateSubObjects();
customization.UpdateRenderers();
}
}
public void SelectBodyColor(bool isForward)
{
currentCustomizationIndex = 0;
CurrentCustomization = Customizations[currentCustomizationIndex];
if(isForward)
{
CurrentCustomization.NextMaterial();
}
else
{
CurrentCustomization.PreviousMaterial();
}
bodyColorText.text = CurrentCustomization.materialIndex.ToString();
}
public void SelectLTrail(bool isForward)
{
currentCustomizationIndex = 1;
CurrentCustomization = Customizations[currentCustomizationIndex];
if(isForward)
{
CurrentCustomization.NextSubObject();
}
else
{
CurrentCustomization.PreviousSubObject();
}
trailText.text = CurrentCustomization.subObjectIndex.ToString();
}
public void SelectRTrail(bool isForward)
{
currentCustomizationIndex = 2;
CurrentCustomization = Customizations[currentCustomizationIndex];
if(isForward)
{
CurrentCustomization.NextSubObject();
}
else
{
CurrentCustomization.PreviousSubObject();
}
trailText.text = CurrentCustomization.subObjectIndex.ToString();
}
}
Customization Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Customization
{
public string DisplayName;
public List<Renderer> Renderers;
public List<Material> Materials;
public List<GameObject> SubObjects;
public int materialIndex;
public int subObjectIndex;
public void NextMaterial()
{
if(materialIndex == Materials.Count - 1)
{
materialIndex = 0;
}
else
{
materialIndex++;
}
UpdateRenderers();
}
public void PreviousMaterial()
{
if(materialIndex == 0)
{
materialIndex = Materials.Count - 1;
}
else
{
materialIndex--;
}
UpdateRenderers();
}
public void NextSubObject()
{
if(subObjectIndex == SubObjects.Count - 1)
{
subObjectIndex = 0;
}
else
{
subObjectIndex++;
}
UpdateSubObjects();
}
public void PreviousSubObject()
{
if(subObjectIndex == 0)
{
subObjectIndex = SubObjects.Count - 1;
}
else
{
subObjectIndex--;
}
UpdateSubObjects();
}
public void UpdateSubObjects()
{
for(var i = 0; i < SubObjects.Count; i++)
if (SubObjects[i])
SubObjects[i].SetActive(i == subObjectIndex);
}
public void UpdateRenderers()
{
foreach (var renderer in Renderers)
if (renderer)
renderer.material = Materials[materialIndex];
}
}
Related
Hey i am beginer and i am making a multiplayer game using mirror by watching https://www.youtube.com/watch?v=w0Dzb4axdcw&list=PLDI3FQoanpm1X-HQI-SVkPqJEgcRwtu7M&index=3 this video in this video he has maded match maker script and i have maded it step by step but don't know why i am getting this error i have seen code many times and all the things are same but he is not getting any error but i am plzz help this is my code and plzz explain in simply i am beginner
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
namespace MirrorBasics {
[System.Serializable]
public class Match {
public string matchID;
public SyncListGameObject players = new SyncListGameObject ();
public Match(string matchID, GameObject player) {
this.matchID = matchID;
players.Add (player);
}
public Match () { }
}
[System.Serializable]
public class SyncListGameObject : SyncList<GameObject> { }
[System.Serializable]
public class SyncListMatch : SyncList<Match> { }
public class MatchMaker : NetworkBehaviour {
public static MatchMaker instance;
public SyncListMatch matches = new SyncListMatch ();
public SyncListString matchIDs = new SyncListString ();
void Start() {
instance = this;
}
public bool HostGame (string _matchID, GameObject _player) {
if (!matchIDs.Contains(_matchID)) {
matchIDs.Add (_matchID) ;
matches.Add (new Match (_matchID, _player));
Debug.Log ($"Match generated");
return true;
} else {
Debug.Log ($"Match ID already exists");
return false;
}
}
public static string GetRandomMatchID () {
string _id = string.Empty;
for (int i = 0; i < 5; i++) {
int random = Random.Range(0, 36);
if (random < 26) {
_id += (char)(random + 65);
} else {
_id += (random - 26).ToString ();
}
}
Debug.Log($"Random Match ID: {_id}");
return _id;
}
}
}
Like SyncListGameObject create SyncList with string like this.
public class SyncListString: SyncList<string>()
Then
public SyncListString matchIDs = new SyncListString();
I made lobby/matchmaking by this tutorial too :)
I'm trying to make my own visual novel in Unity.
I made a text manager script to load the text files and to read them correctly and a text box script to load the text onto the text box. In my hierachy I made two objects, one for the text box script and the other for the dialogue manager. (DialogueParserObj)
My goal was it to put the text file into the text box, which is seen as the dialogue string variable in the TextBox script so you could see the actual text file in the dialogue box I have marked. But it remains empty, and I don't know why and I don't get any errors.
I would really appreciate your help or other suggestions to go about a well structured dialogue system!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DialogueBox : MonoBehaviour
{
TextManager parser;
public string dialogue;
int lineNum;
public GUIStyle customStyle;
void Start()
{
dialogue = "";
parser = GameObject.Find("DialogueParserObj").GetComponent<TextManager>();
lineNum = 0;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Return))
{
dialogue = parser.GetContent(lineNum);
lineNum++;
}
}
void OnGUI()
{
dialogue = GUI.TextField(new Rect(100, 400, 600, 200), dialogue, customStyle);
}
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
public class TextManager : MonoBehaviour
{
string readPath;
List<string> stringList = new List<string>();
List<DialogueLine> lines = new List<DialogueLine>();
struct DialogueLine
{
public string name;
public string content;
public int pose;
public DialogueLine(string n, string c, int p)
{
name = n;
content = c;
pose = p;
}
}
void Start()
{
readPath = Application.dataPath + "/text.txt";
ReadFile(readPath);
}
public string GetName(int lineNumber)
{
if (lineNumber < lines.Count)
{
return lines[lineNumber].name;
}
return "";
}
public string GetContent(int lineNumber)
{
if (lineNumber < lines.Count)
{
return lines[lineNumber].content;
}
return "";
}
public int GePose(int lineNumber)
{
if (lineNumber < lines.Count)
{
return lines[lineNumber].pose;
}
return 0;
}
void ReadFile(string filePath)
{
StreamReader r = new StreamReader(filePath);
while (!r.EndOfStream)
{
string line = r.ReadLine();
if (line != null)
{
string[] lineValues = line.Split('|');
DialogueLine lineEntry = new DialogueLine(lineValues[0], lineValues[1], int.Parse (lineValues [2]));
stringList.Add(line);
}
}
r.Close();
}
Inside the manager script I have a method that start a dialogue name : StartDialogue:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DialogueManager : MonoBehaviour
{
public Text dialogueText;
public Text nameText;
public float sentencesSwitchDuration;
public bool animateSentenceChars = false;
public GameObject canvas;
public static bool dialogueEnded = false;
public DialogueTrigger trigger;
private Queue<string> sentence;
// Use this for initialization
void Start()
{
sentence = new Queue<string>();
}
public void StartDialogue(Dialogue dialogue)
{
canvas.SetActive(true);
nameText.text = dialogue.name;
sentence.Clear();
foreach (string sentence in dialogue.sentences)
{
this.sentence.Enqueue(sentence);
}
DisplayNextSentence();
}
public void DisplayNextSentence()
{
if (this.sentence.Count == 0)
{
EndDialogue();
return;
}
string sentence = this.sentence.Dequeue();
dialogueText.text = sentence;
StopAllCoroutines();
StartCoroutine(DisplayNextSentenceWithDelay(sentence));
}
public IEnumerator DisplayNextSentenceWithDelay(string sentence)
{
if (animateSentenceChars)
{
dialogueText.text = "";
foreach (char letter in sentence.ToCharArray())
{
dialogueText.text += letter;
yield return null;
}
}
yield return new WaitForSeconds(sentencesSwitchDuration);
DisplayNextSentence();
}
private void EndDialogue()
{
dialogueEnded = true;
if (trigger.dialogueNum == trigger.conversations[trigger.dialogueIndex].Dialogues.Count)
canvas.SetActive(false);
Debug.Log("End of conversation.");
}
}
Then in the trigger script I have a method name TriggerDialogue that get index number. For example index 0 it will start the dialoue/s of the first conversation. But in fact it's just starting the first dialogue from the dialogues List.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
[ExecuteInEditMode]
public class DialogueTrigger : MonoBehaviour
{
public List<Conversation> conversations = new List<Conversation>();
//public List<Dialogue> dialogue = new List<Dialogue>();
[HideInInspector]
public int dialogueNum = 0;
[HideInInspector]
public int dialogueIndex = 0;
private bool triggered = false;
private List<Dialogue> oldDialogue;
private bool activateButton = false;
public void TriggerDialogue(int dialogueIndex)
{
this.dialogueIndex = dialogueIndex;
if (conversations.Count > 0 &&
conversations[dialogueIndex].Dialogues.Count > 0)
{
if (triggered == false)
{
if (FindObjectOfType<DialogueManager>() != null)
{
FindObjectOfType<DialogueManager>().StartDialogue(conversations[dialogueIndex].Dialogues[dialogueNum]);
dialogueNum += 1;
}
triggered = true;
}
}
}
private void Update()
{
ButtonActivation();
if (DialogueManager.dialogueEnded == true)
{
if (dialogueNum == conversations[dialogueIndex].Dialogues.Count)
{
return;
}
else
{
FindObjectOfType<DialogueManager>().StartDialogue(conversations[dialogueIndex].Dialogues[dialogueNum]);
DialogueManager.dialogueEnded = false;
dialogueNum += 1;
}
}
}
public bool ActivateButton()
{
return activateButton;
}
private void ButtonActivation()
{
if (ConversationsChecks() == true)
{
foreach (string sentence in conversations[dialogueIndex].Dialogues[dialogueNum].sentences)
{
if (sentence != "")
{
activateButton = true;
}
else
{
activateButton = false;
}
}
}
else
{
activateButton = false;
}
}
public void SaveConversations()
{
string jsonTransform = JsonHelper.ToJson(conversations.ToArray(), true);
File.WriteAllText(#"d:\json.txt", jsonTransform);
}
public void LoadConversations()
{
string jsonTransform = File.ReadAllText(#"d:\json.txt");
conversations.Clear();
conversations.AddRange(JsonHelper.FromJson<Conversation>(jsonTransform));
}
private bool ConversationsChecks()
{
bool IsConversationsReady = false;
if (conversations.Count > 0 &&
conversations[dialogueIndex].Dialogues.Count > 0 &&
conversations[dialogueIndex].Dialogues[dialogueNum].sentences.Count > 0 &&
conversations[dialogueIndex].Dialogues[dialogueNum].name != "" &&
conversations[dialogueIndex].name != "")
{
IsConversationsReady = true;
}
else
{
IsConversationsReady = false;
}
return IsConversationsReady;
}
}
Then I have more two small classes :
Dialogue:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Dialogue
{
[Tooltip("Dialogue Name")]
public string name;
[TextArea(1, 10)]
public List<string> sentences = new List<string>();
}
And Conversation :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Conversation
{
[Tooltip("Conversation Name")]
public string name;
public List<Dialogue> Dialogues = new List<Dialogue>();
}
So now when I want to start a dialogue I'm calling the TriggerDialogue method like this example :
dialogueTrigger.TriggerDialogue(0);
Instead I want to do something like that :
dialogueTrigger.StartConversation("Opening Scene");
Or
dialogueTrigger.StartConversation("The last conversation");
And this is example screenshot of how the Inspector of the conversations and dialogues looks like :
Conversations
So if for example I want to start the first conversation somewhere in my game I will do :
dialogueTrigger.StartConversation("The Opening");
And it will start the dialogue/s inside the "The Opening" conversation.
Using the index is working fine but I want to use to start a conversation by the conversation name it will be easier.
Given that you are using a List<T>, if you move away from using the index to get the item you want, you will need to enumerate the collection each time to find that same item. The best you can do here, is change the data structure to a Dictionary, so you can search for it by the Key and avoid the performance hit. In order to also avoid having to remember what names you put to the conversations, perhaps it would be best to use an Enum.
So, create the enum:
public enum SceneConversations
{
OpeningScene = 1,
// ...
}
and start using
public class DialogueTrigger : MonoBehaviour
{
public Dictionary<SceneConversations, Conversation> conversations = new Dictionary<SceneConversations, Conversation>();
you can then use
public void StartConversation(SceneConversations conversationWanted) {}
and call it with
dialogueTrigger.StartConversation(SceneConversations.OpeningScene);
If I remember correctly, this has the added advantage that Unity will show you a drop-down for the possible values of SceneConversations, so that's also easier to handle.
I have four buttons using the same prefab and holding 4 text elements from an array out of which only one is assigned bool value to true. I am trying to access that true element when any of false element is clicked. i want to highlight true element when the false element is clicked. can anyone please help me to achieve this functionality?
using simpleobjectpool
taking reference from unity quiz game tutorial
Thanks
Answer Button Script
public class AnswerButton : MonoBehaviour
{
public Text answerText;
private AnswerData answerData;
private GameController gameController;
private bool isCorrect;
void Start()
{
gameController = FindObjectOfType<GameController>();
}
public void Setup(AnswerData data)
{
answerData = data;
answerText.text = answerData.answerText;
}
public void HandleClick()
{
gameController.AnswerButtonClicked(answerData.isCorrect);
{
if (answerData.isCorrect)
{
}
if (!answerData.isCorrect)
{
}
}
Answer Data Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class AnswerData
{
public string answerText;
public bool isCorrect;
}
QuestionData Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class QuestionData
{
public string questionText;
public AnswerData[] answers;
}
Game Controller Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System;
public class GameController : MonoBehaviour
{
public Text questionText;
public Text scoreDisplayText;
public SimpleObjectPool answerButtonObjectPool;
public Transform answerButtonParent;
public GameObject questionPanel;
public GameObject roundOverPanel;
public GameObject levelsPanel;
private DataController dataController;
private RoundData currentRoundData;
private bool isRoundActive;
private float timeBeetweenQuestions = 3.0f;
private List<GameObject> answerButtonGameObjects = new List<GameObject>();
private QuestionData[] questionPool;
private int questionIndex;
private int qNumber = 0;
private List<int> questionIndexesChosen = new List<int>();
public int playerScore = 0;
public int totalQuestions;
private static int pointAddedForCorrectAnswer;
public AudioSource answerButtonClicked;
public AudioSource wrongAnswerClicked;
void Start ()
{
dataController = FindObjectOfType<DataController>();
currentRoundData = dataController.GetCurrentRoundData();
questionPool = currentRoundData.questions;
playerScore = 0;
questionIndex = 0;
scoreDisplayText.text = "Score: " + playerScore.ToString();
isRoundActive = true;
ShowQuestion();
}
private void ShowQuestion()
{
RemoveAnswerButtons();
QuestionData questionData = questionPool[questionIndex];
questionText.text = questionData.questionText;
for (int i = 0; i < questionData.answers.Length; i++)
{
GameObject answerButtonGameObject =
answerButtonObjectPool.GetObject();
answerButtonGameObjects.Add(answerButtonGameObject);
answerButtonGameObject.transform.SetParent(answerButtonParent);
AnswerButton answerButton =
answerButtonGameObject.GetComponent<AnswerButton>();
AnswerButton.Setup(questionData.answers[i]);
}
}
private void RemoveAnswerButtons()
{
while (answerButtonGameObjects.Count > 0)
{
answerButtonObjectPool.ReturnObject(answerButtonGameObjects[0]);
answerButtonGameObjects.RemoveAt(0);
}
}
IEnumerator TransitionToNextQuestion()
{
yield return new WaitForSeconds(timeBeetweenQuestions);
ShowQuestion();
}
IEnumerator WaitForFewSeconds()
{
yield return new WaitForSeconds(timeBeetweenQuestions);
EndRound();
}
IEnumerator ReturnCorrectButtonColor()
{
Debug.Log("im correct");
GetComponent<Button>().image.color = Color.green;
yield return new WaitForSeconds(seconds: 2.9f);
GetComponent<Button>().image.color = Color.white;
}
IEnumerator ReturnWrongButtonColor()
{
Debug.Log("im wrong");
GetComponent<Button>().image.color = Color.red;
yield return new WaitForSeconds(seconds: 2.9f);
GetComponent<Button>().image.color = Color.white;
}
public void AnswerButtonClicked (bool isCorrect)
{
if (isCorrect)
{
playerScore += currentRoundData.pointAddedForCorrectAnswer;
scoreDisplayText.text = "Score: " + playerScore.ToString();
//play coorect answer sound
answerButtonClicked.Play();
StartCoroutine(ReturnCorrectButtonColor());
}
if (!isCorrect)
{
//play wrong answer sound
answerButtonClicked = wrongAnswerClicked;
answerButtonClicked.Play();
StartCoroutine(ReturnWrongButtonColor());
// buttons = GameObject.FindGameObjectsWithTag("Answer");
// {
// foreach (GameObject button in buttons)
// {
// if (button.GetComponent<AnswerButton>
//().answerData.isCorrect)
// {
// button.GetComponent<AnswerButton>
// ().StartCoroutine(ReturnCorrectButtonColor());
// }
// }
//}
}
if (qNumber < questionPool.Length - 1) /
{
qNumber++;
StartCoroutine(TransitionToNextQuestion());
}
else
{
StartCoroutine(WaitForFewSeconds());
}
}
public void EndRound()
{
isRoundActive = false;
questionPanel.SetActive(false);
roundOverPanel.SetActive(true);
}
//on button click return to main menu
public void ReturnToMenu ()
{
SceneManager.LoadScene("MenuScreen");
}
}
In order to highlight both Wrong (the clicked one) and the Right buttons you need to have access to both buttons. This means that you can't do highlighting from HandleClick method of your Answer Button Script, as it only has access to itself, e.g. to the Wrong button.
The good thing is that this method notifies GameController that the button has been clicked. GameController knows about all the buttons, so it can easily highlight both buttons.
So, instead of launching your highlight subroutines from Answer Button's HandleClick, you should do this from GameController's AnswerButtonClicked: identify both the Right button and the clicked button there and launch appropriate subroutines for them.
Update:
For instance, your ReturnCorrectButtonColor would look like:
IEnumerator ReturnCorrectButtonColor( GameObject button )
{
Debug.Log("im correct");
button.GetComponent<Button>().image.color = Color.green;
yield return new WaitForSeconds(seconds: 2.9f);
button.GetComponent<Button>().image.color = Color.white;
}
so in AnswerButtonClicked you identify which button to highlight as a correct answer button and pass it as a paramter to this method:
StartCoroutine(ReturnCorrectButtonColor(correctButton));
Currently i'm developing a quiz kind of game. I've managed to develop the basic working of it. I was using the serialized field for updating the questions. Now i'm planning to use a CSV file for the questions.
CSVReader
using UnityEngine;
using System.Collections.Generic;
public class CSVReader : MonoBehaviour
{
public TextAsset csvFile;
[System.Serializable]
public class Row
{
public string Id;
public string Fact;
public string IsTrue;
}
public static List<Row> rowList = new List<Row>();
bool isLoaded = false;
void Start()
{
Load(csvFile);
}
public bool IsLoaded()
{
return isLoaded;
}
public List<Row> GetRowList()
{
return rowList;
}
public void Load(TextAsset csv)
{
rowList.Clear();
string[][] grid = CsvParser2.Parse(csv.text);
for (int i = 1; i < grid.Length; i++)
{
Row row = new Row();
row.Id = grid[i][0];
row.Fact = grid[i][1];
row.IsTrue = grid[i][2];
rowList.Add(row);
}
isLoaded = true;
}
public int NumRows()
{
return rowList.Count;
}
public static Row GetAt(int i)
{
if (rowList.Count <= i)
return null;
return rowList[i];
}
public static Row Find_Id(string find)
{
return rowList.Find(x => x.Id == find);
}
public List<Row> FindAll_Id(string find)
{
return rowList.FindAll(x => x.Id == find);
}
public static Row Find_Fact(string find)
{
return rowList.Find(x => x.Fact == find);
}
public List<Row> FindAll_Fact(string find)
{
return rowList.FindAll(x => x.Fact == find);
}
public static Row Find_IsTrue(string find)
{
return rowList.Find(x => x.IsTrue == find);
}
public List<Row> FindAll_IsTrue(string find)
{
return rowList.FindAll(x => x.IsTrue == find);
}
}
I'm trying to assign the values to this question class
using UnityEngine;
public class Question : MonoBehaviour
{
CSVReader csvr = new CSVReader();
public string Fact;
public bool IsTrue;
public void Start()
{
GameObject PlayCon = GameObject.FindWithTag("GameController");
if (PlayCon != null)
{
csvr = PlayCon.GetComponent<CSVReader>();
}
if (csvr == null)
{
Debug.Log("Cannot find 'GameController' script");
}
}
public void FixedUpdate()
{
for (int i = 1; i <= 2; i++)
{
Fact = CSVReader.Find_Id("i").Fact;
Debug.Log(Fact);
if (CSVReader.Find_Id("i").IsTrue == "true")
{
IsTrue = true;
}
else
IsTrue = false;
}
}
}
My game manager for generating questions
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Linq;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour {
public Question[] facts;
private static List<Question> unansweredfacts;
private Question currentfacts;
[SerializeField]
private Text FactText;
[SerializeField]
private float TimeBetweenFacts = 1f;
[SerializeField]
private Text TrueAnswerText;
[SerializeField]
private Text FalseAnswerText;
[SerializeField]
private Animator animator;
[SerializeField]
public GameObject canvasquiz;
CSVReader csvr = new CSVReader();
void Start()
{
if (unansweredfacts == null || unansweredfacts.Count == 0)
{
unansweredfacts = facts.ToList<Question>();
}
SetCurrentfact();
Debug.Log(currentfacts.Fact + "is" + currentfacts.IsTrue);
}
void SetCurrentfact()
{
int RandomFactIndex = Random.Range(0, unansweredfacts.Count);
currentfacts = unansweredfacts[RandomFactIndex];
FactText.text = currentfacts.Fact;
if (currentfacts.IsTrue)
{
TrueAnswerText.text = "CORRECT !";
FalseAnswerText.text = "WRONG !";
}
else
{
TrueAnswerText.text = "WRONG !";
FalseAnswerText.text = "CORRECT !";
}
}
IEnumerator TransitionToNextFact()
{
unansweredfacts.Remove(currentfacts);
canvasquiz.SetActive(false);
yield return new WaitForSeconds(TimeBetweenFacts);
SetCurrentfact();
canvasquiz.SetActive(true);
}
public void UserSelected(bool isTrue)
{
animator.SetTrigger(isTrue.ToString());
//Debug.Log(isTrue.ToString);
if (currentfacts.IsTrue == isTrue)
{
Debug.Log("CORRECT !");
}
else
{
Debug.Log("WRONG !");
}
StartCoroutine(TransitionToNextFact());
}
Getting a NullReferenceException on SetCurrentFact() every time i try doing this. Even tried assigning the values directly on that method. Being stuck up on this for 2 days. Is there any way i can do this. I know i'm missing something. Sorry for my messed up code.
it appears facts field is not initialized before using.
but that would cause the error in Start method instead of SetCurrentfact