Documentation for the Unity C# Library
Loading...
Searching...
No Matches
QuizDisplay.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Linq;
5using PixoVR.Audio;
6using PixoVR.Core;
7using UnityEngine;
8using UnityEngine.UI;
9using TMPro;
10using UnityEngine.EventSystems;
11using PixoVR.Apex;
12using PixoVR.Apex.XAPI;
14using TinCan;
15
16namespace PixoVR.Event
17{
19 {
20 [Space] [SerializeField] private CanvasGroup _canvasGroup;
21 [SerializeField] private NearWaypoint _nearWaypoint;
22 [SerializeField] private QuizData _quizData;
23 [SerializeField] private TMP_Text _questionText;
24 [SerializeField] private AnswerOption[] _answerOptions;
25 [SerializeField] private Button _confirmButton;
26 [SerializeField] private TMP_Text _confirmText;
27 [SerializeField] private TMP_Text singleText;
28 [SerializeField] private string sfxCorrectAnswer;
29 [SerializeField] private string sfxIncorrectAnswer;
30 [SerializeField] private string sfxFixBrokenItem;
31 [SerializeField] private string sfxClick;
32 [SerializeField] private GameObject[] _additionalItemsToEnable;
33 [SerializeField] private List<VisibilityControlPoint> _visibilityControlPoints;
34
35 [SerializeField] private int currentQuestionIndex;
36 [Space] [SerializeField] private bool _objectsShouldBeRepaired = false;
37 [SerializeField] private bool _correectAnswerShouldBeCleanedForNone = false;
38 [SerializeField] private bool _useNearWaypoint = false;
39
41 private string _selectedAnswer;
44 private bool _isItemBroken;
45 private int _brokenID;
46 private bool _isShouldWaitForEndingVO = false;
47
49 private bool _isAnswerSaved = false;
50 [Space] public int _selectedAnswerOptionID;
51
55
56 private void Start()
57 {
62
65 }
66
67 private void SubscribeOnToggles()
68 {
69 for (int i = 0; i < _answerOptions.Length; i++)
70 {
73 }
74 }
75
76 private void UnsubscribeOnToggles()
77 {
78 for (int i = 0; i < _answerOptions.Length; i++)
79 {
81 }
82 }
83
84 private void ClearAnswersHistory()
85 {
86 foreach (var quiz in _quizData.ListOfQuizzes)
87 {
88 foreach (var question in quiz.Questions)
89 {
90 question.ClearAnswers();
91 }
92 }
93 }
95 private void OnConfirmButtonClick()
96 {
99 }
101 private void UpdateStepManager()
102 {
103 _confirmButton.interactable = false;
105 var questionInformation = _currentQuiz.Questions[currentQuestionIndex];
106
108 {
109 if (!_isAnswerSaved)
110 {
111 _isAnswerSaved = true;
112 questionInformation.SetSelectedAnswer(_selectedAnswer);
113 }
114
116 {
117 if (_itemIdInQuestion != ItemsEnum.NONE)
120 {
121 RepairObject(questionInformation.BreakableObjectID);
122 }
123 else
124 {
125 SetInspectedMark(questionInformation.BreakableObjectID);
126 }
128
129 _isAnswerSaved = false;
131
133 }
134 else
136 EventSystem.current.SetSelectedGameObject(null);
137 }
138 }
139
140 else
141 {
142 if (!_isAnswerSaved)
143 {
144 _isAnswerSaved = true;
145 questionInformation.SetSelectedAnswer(_selectedAnswer);
147
149 {
150 if (_itemIdInQuestion != ItemsEnum.NONE)
151 {
153 {
154 RepairObject(questionInformation.BreakableObjectID);
155 }
156
157 else
158 {
159 SetInspectedMark(questionInformation.BreakableObjectID);
160 }
161 }
162
163 _isAnswerSaved = false;
164
166 {
167 Hide();
168 }
169 }
170 else
171 {
172 EventSystem.current.SetSelectedGameObject(null);
173 }
174 }
175
176 SendApexEvents(questionInformation);
177 }
178
179 private void SendApexEvents(QuestionInformation questionInformation)
180 {
181 if (!_apexSessionState.IsLoggedIn) return;
182
183 var eventData = new Dictionary<string, string>
184 {
185 { "Time", $"{DateTime.UtcNow}" },
186 { "Question", $"{questionInformation.Question}" },
187 { "Correct Answer", $"{questionInformation.GetCorrectAnswer()}" },
188 { "Given Answer", $"{questionInformation.GetSelectedAnswer()}" },
189 { "Earned Score", $"{questionInformation.GetEarnedScoring()}" },
190 { "Max Score", $"{questionInformation.Scoring}" }
191 };
192
193 ApexSystem.SendSimpleSessionEvent("Custom event", "",
194 new Extension(eventData));
195 }
196
197 private bool IsLastQuestion()
198 {
199 return currentQuestionIndex == _currentQuiz.Questions.Count - 1;
200 }
201
202 private void OnToggleSelected(string selectedAnswer, bool isCorrect, int optionID)
203 {
205 _selectedAnswer = selectedAnswer;
206 _isSelectedCorrectAnswer = isCorrect;
207 _confirmButton.interactable = true;
208
209 if (_selectedAnswerOptionID == optionID) return;
210
212 {
214 }
215
216 _selectedAnswerOptionID = optionID;
217 }
218
219 private void RepairObject(ItemsEnum itemId)
220 {
222 }
223
224 private void SetInspectedMark(ItemsEnum itemId)
225 {
227 }
228
229 private void SetQuestionInformation()
231 _confirmButton.interactable = false;
234 }
235
236 private void SetAnswersOptions(QuestionInformation questionInformation)
237 {
238 var optionsAnswers = questionInformation.OptionsAnswers;
239 _itemIdInQuestion = questionInformation.BreakableObjectID;
240 var VO_Description = questionInformation.VO_ID_DescriptionForAnswer;
241 if (VO_Description != string.Empty)
242 {
243 PlayFeedbackVoiceOver(VO_Description);
244 }
245
246 _isItemBroken = false;
247
254
255 // var correctAnswers = _isItemBroken
256 // ? questionInformation.CorrectAnswerID_Broken
257 // : questionInformation.CorrectAnswerID_IfNotBroken;
258
259 List<int> correctAnswers;
260 if (_isItemBroken)
261 {
262 if (_brokenID == 0)
263 {
264 correctAnswers = questionInformation.CorrectAnswerID_Broken;
265 }
266 else
267 {
268 correctAnswers = questionInformation.CorrectAnswersID_AdditionalBroken[_brokenID - 1].Answers;
269 }
271 else
272 {
273 correctAnswers = questionInformation.CorrectAnswerID_IfNotBroken;
274 }
276 for (int i = 0; i < _answerOptions.Length; i++)
277 {
278 _answerOptions[i].gameObject.SetActive(true);
279
280 if (i < optionsAnswers.Count)
281 {
282 _answerOptions[i].SetSelected(false);
283 _answerOptions[i].SetText(optionsAnswers[i]);
285 }
286
287 else
288 {
289 _answerOptions[i].gameObject.SetActive(false);
290 }
291 }
292
293 foreach (var answer in correctAnswers)
294 {
295 var answers = questionInformation.OptionsAnswers;
296 _currentQuiz.Questions[currentQuestionIndex].SetCorrectAnswer(answers[answer]);
297 _answerOptions[answer].SetCorrectnes(true);
298 }
299 }
300
301 private void PlayFeedbackVoiceOver(string idVo, bool isLastQuestion = true, bool isVoMustFinished = false)
302 {
303 if (isVoMustFinished)
304 {
306 _canvasGroup.interactable = false;
307 _confirmButton.interactable = false;
308 if (isLastQuestion)
309 {
310 _audioService.RepeatableAudioStopped += Hide;
311 }
312 else
313 {
314 _audioService.RepeatableAudioStopped += () =>
315 {
317 _canvasGroup.interactable = true;
318 };
319 }
320 }
321 else
322 {
324 }
325
326 EventBetter.Raise(new GuideVoiceOverPlayEvent()
327 {
328 VoiceOverName = idVo
329 });
330
332 }
333
334 private void SetQuestionText(string questionText)
335 {
336 _questionText.SetText(questionText);
337 }
338
339 private void PlayAudio()
340 {
342
343 var scenarioState = StatesService.GetState<ScenarioState>();
344
345 var questionInformation = _currentQuiz.Questions[currentQuestionIndex];
346
347 if (_itemInQuestion == null ||
348 (_itemIdInQuestion == ItemsEnum.NONE
350 {
354
355 if (questionInformation.VO_ID_RightAnswer_NotBroken == string.Empty
356 || scenarioState.IsEvaluation) return;
357
358 PlayFeedbackVoiceOver(questionInformation.VO_ID_RightAnswer_NotBroken, IsLastQuestion(), true);
359 }
360 else
361 {
363
364 if (questionInformation.VO_ID_Incorrect_NotBroken == string.Empty
365 || scenarioState.IsEvaluation) return;
366
367 PlayFeedbackVoiceOver(questionInformation.VO_ID_Incorrect_NotBroken);
368 }
369 }
370
371 else
372 {
373 if (_isItemBroken)
374 {
376 {
378
379 if ((questionInformation.VO_ID_RightAnswerBroken == string.Empty && _brokenID == 0)
380 || (_brokenID > 0 &&
381 questionInformation.VO_ID_RightAnswersAdditionalBroken[_brokenID - 1] == string.Empty)
382 || scenarioState.IsEvaluation)
383 {
389 else
392 _brokenID == 0
393 ? questionInformation.VO_ID_RightAnswerBroken
394 : questionInformation.VO_ID_RightAnswersAdditionalBroken[_brokenID - 1],
396 true);
397
399 {
401 }
402 }
403 }
404 else
405 {
407
408 if ((questionInformation.VO_ID_Incorrect_Broken == string.Empty && _brokenID == 0) ||
409 (_brokenID > 0 && questionInformation.VO_ID_Incorrect_AdditionalBroken[_brokenID - 1] ==
410 string.Empty)
411 || scenarioState.IsEvaluation) return;
412
414 ? questionInformation.VO_ID_Incorrect_Broken
415 : questionInformation.VO_ID_Incorrect_AdditionalBroken[_brokenID - 1]);
416 }
417 }
418 else
419 {
421 {
423
424 if (questionInformation.VO_ID_RightAnswer_NotBroken == string.Empty
425 || scenarioState.IsEvaluation) return;
426
427 PlayFeedbackVoiceOver(questionInformation.VO_ID_RightAnswer_NotBroken, IsLastQuestion(),
428 true);
429 }
430 else
431 {
433
434 if (questionInformation.VO_ID_Incorrect_NotBroken == string.Empty
435 || scenarioState.IsEvaluation) return;
436
437 PlayFeedbackVoiceOver(questionInformation.VO_ID_Incorrect_NotBroken);
438 }
439 }
440 }
441 }
442
443 private void Hide()
444 {
446
447 EventBetter.Raise(new TriggeredItemEvent()
448 {
449 item = ItemId
450 });
451
452 _audioService.RepeatableAudioStopped -= Hide;
453 _confirmButton.interactable = false;
454
455 Interactive(false);
456
457
458 _visibilityControlPoints?.ForEach(x => x.enabled = false);
459 }
460
461 public override void OpenInspectionMenu(string quizID)
462 {
463 _confirmButton.interactable = false;
464 Interactive(true);
466
468
469 var firstQuestion = _currentQuiz.Questions[0];
470
471 SetQuestionText(firstQuestion.Question);
472 SetAnswersOptions(firstQuestion);
473 }
474
475
476 public override void Interactive(bool isInteractive)
477 {
478 bool isAlreadySubscribe = IsActive;
479 IsActive = isInteractive;
480 _canvasGroup.alpha = isInteractive ? 1 : 0;
481 _canvasGroup.blocksRaycasts = isInteractive;
482 _canvasGroup.interactable = isInteractive;
483
484 EnableAdditionalItems(isInteractive);
485
486 _visibilityControlPoints?.ForEach(x => x.enabled = isInteractive);
487
488 if (isInteractive && !isAlreadySubscribe)
489 {
491
492 _confirmButton.onClick.AddListener(OnConfirmButtonClick);
493 }
495 else if (!isInteractive)
496 {
498
499 _confirmButton.onClick.RemoveListener(OnConfirmButtonClick);
500 }
501
502 if (isInteractive && _useNearWaypoint)
503 {
505 }
506 }
507
508 private void EnableAdditionalItems(bool isActive)
509 {
510 if (_additionalItemsToEnable != null && _additionalItemsToEnable.Length > 0)
511 {
512 foreach (var go in _additionalItemsToEnable)
513 {
514 go.SetActive(isActive);
515 }
516 }
517 }
518
519 public override void SetParametersForItem(string quizId, string[] additionalValues)
520 {
522 var firstQuestion = _currentQuiz.Questions[0];
523
524 firstQuestion.SetCorrectAnswer(additionalValues[0]);
525 firstQuestion.SetSelectedAnswer(additionalValues[1]);
526
527 SetInspectedMark(firstQuestion.BreakableObjectID);
528 }
529 }
530}
Main logic for playing fxs and voice overs.
int PlayFX(string fxName)
Play FX by fx name.
void StopAllVoiceOvers()
Stop all voice overs.
void PlayRepeatable(string voiceOverName)
Play voice repeating it at a certain time intervals.
Intentionally made partial, in case you want to extend it easily.
Unity components communication service.
s Base class for interactable objects with which the step manager interacts. It also stores a set of ...
virtual void RepairElement()
Remove from the broken state object.
List< ListAnswer > CorrectAnswersID_AdditionalBroken
Definition QuizData.cs:75
List< int > CorrectAnswerID_IfNotBroken
Definition QuizData.cs:73
ItemsEnum BreakableObjectID
[SerializeField]
Definition QuizData.cs:69
Quiz GetQuizItem(string quizID="")
Definition QuizData.cs:16
List< Quiz > ListOfQuizzes
Definition QuizData.cs:14
NearWaypoint _nearWaypoint
[SerializeField]
TMP_Text singleText
[SerializeField]
void PlayFeedbackVoiceOver(string idVo, bool isLastQuestion=true, bool isVoMustFinished=false)
override void SetParametersForItem(string quizId, string[] additionalValues)
void SendApexEvents(QuestionInformation questionInformation)
QuizData _quizData
[SerializeField]
void OnToggleSelected(string selectedAnswer, bool isCorrect, int optionID)
Button _confirmButton
[SerializeField]
string sfxFixBrokenItem
[SerializeField]
void SetAnswersOptions(QuestionInformation questionInformation)
TMP_Text _questionText
[SerializeField]
override void OpenInspectionMenu(string quizID)
Enable inpection menu UI.
InteractableClass _itemInQuestion
void SetQuestionText(string questionText)
void RepairObject(ItemsEnum itemId)
void SetInspectedMark(ItemsEnum itemId)
GameObject[] _additionalItemsToEnable
[SerializeField]
AnswerOption[] _answerOptions
[SerializeField]
override void Interactive(bool isInteractive)
ApexSessionState _apexSessionState
string sfxCorrectAnswer
[SerializeField]
bool _useNearWaypoint
[SerializeField]
bool _correectAnswerShouldBeCleanedForNone
[SerializeField]
int currentQuestionIndex
[SerializeField]
void EnableAdditionalItems(bool isActive)
string sfxClick
[SerializeField]
List< VisibilityControlPoint > _visibilityControlPoints
[SerializeField]
TMP_Text _confirmText
[SerializeField]
string sfxIncorrectAnswer
[SerializeField]
[Serializable]
Definition QuizData.cs:37
List< QuestionInformation > Questions
Definition QuizData.cs:40
Logic for saving and unloading states during project execution.
Main system for working with steps lists.
InteractableClass GetGameObjectByID(ItemsEnum itemId)
Get scene object by item id.
void SetCorrectnes(bool isCorrect)
void SetText(string option)
void SetSelected(bool isSelected)
Action< string, bool, int > ToggleSelected
ItemsEnum
Represents a list of ID for interactable objects.
Definition ItemsEnum.cs:11