2017-05-20 11:23:09 +03:00
using System.Collections.Generic ;
2017-05-17 14:11:01 +02:00
using System.Linq ;
using System.Text.RegularExpressions ;
using UnityEngine ;
using UnityEngine.UI ;
2017-05-20 18:29:26 +03:00
using UnityEngine.SceneManagement ;
2017-05-17 14:11:01 +02:00
2017-05-20 16:43:03 +03:00
public class Quiz4Controller : MonoBehaviour {
2017-05-17 14:11:01 +02:00
2017-05-20 11:23:09 +03:00
// References to answers
private List < GameObject > answers ;
// References to answers halo prefabs
private List < GameObject > answersHaloEffects ;
2017-05-17 14:11:01 +02:00
public Text counterText ;
public Text scoreText ;
public Text questionText ;
public Button btnNextQuestion ;
2017-05-20 11:23:09 +03:00
public GameObject haloEffect ;
public GameObject [ ] answerModels ;
2017-05-19 22:38:58 +03:00
private int scoreValue = 0 ;
private int questionIdx = 0 ;
2017-05-17 14:11:01 +02:00
2017-05-17 15:40:49 +02:00
private const int numberOfAnswers = 4 ;
2017-05-17 14:11:01 +02:00
2017-05-17 15:40:49 +02:00
private const int scoreCorrectAnswer = 10 ;
private const int scoreIncorrectAnswer = - 15 ;
private const int scoreTimedOut = 0 ;
private const int counterInitialValue = 10 ;
2017-05-18 22:10:17 +03:00
private const int counterDisplayAnswersInitialValue = 3 ;
2017-05-19 22:38:58 +03:00
private float counterValue ;
2017-05-18 22:10:17 +03:00
private float counterDisplayAnswersValue ;
private bool counterDisplayAnswersStarted = false ;
2017-05-17 14:11:01 +02:00
2017-05-19 22:38:58 +03:00
// List of selected answers
2017-05-17 14:11:01 +02:00
private List < int > selectedAnswers ;
2017-05-19 22:38:58 +03:00
// List of questions and correct answers
2017-05-17 14:11:01 +02:00
List < Question > questions = new List < Question > ( ) {
2017-05-20 11:23:09 +03:00
new Question ( "1. Neki od ovih prozora imaju 2-3 puta manje toplotnih gubitaka za razliku od drugih, koji su to?" , new int [ ] { 1 , 4 } ,
new Answer [ ] {
new Answer ( AnswerObjectModel . NOVI_PROZOR , "Novi prozor" ) ,
new Answer ( AnswerObjectModel . STARI_PROZOR , "Stari prozor" ) ,
new Answer ( AnswerObjectModel . SLOMLJENI_PROZOR , "Slomljeni prozor" ) ,
new Answer ( AnswerObjectModel . PROZOR_SA_ROLETNOM , "Prozor sa roletnom" ) } ) ,
new Question ( "2. Na jedan od načina možete uštedjeti i do 10 litara vode po osobi dnevno, uz koji predmet?" , new int [ ] { 3 , 4 } ,
new Answer [ ] {
new Answer ( AnswerObjectModel . UPALJENA_CESMA , "Upaljena česma" ) ,
new Answer ( AnswerObjectModel . PROZOR_SA_ROLETNOM , "Spuštene roletne" ) ,
new Answer ( AnswerObjectModel . UGASENA_CESMA , "Ugašena česma" ) ,
new Answer ( AnswerObjectModel . PROFESOR_ATOM_10 , "Profesor Atom +10" ) } ) ,
new Question ( "3. Korištenjem jednog od sljedećih predmeta, u svjetlost se pretvara svega 5% uložene energije, dok se ostatak pretvara u toplotu, koji je to?" , new int [ ] { 1 } ,
new Answer [ ] {
new Answer ( AnswerObjectModel . ZARNA_SIJALICA , "Žarne sijalice" ) ,
new Answer ( AnswerObjectModel . BICIKLO , "Biciklo" ) ,
new Answer ( AnswerObjectModel . VENTILATOR , "Ventilator" ) ,
new Answer ( AnswerObjectModel . KANTA_ZA_RECIKLIRANJE , "Kanta za recikliranje" ) } ) ,
new Question ( "4. Neki od navedenih predmeta uključeni u utičnicu, iako nisu u u funkciji, i dalje se znatno griju i troše električnu energiju." , new int [ ] { 3 } ,
new Answer [ ] {
new Answer ( AnswerObjectModel . NOVI_PROZOR , "Prozor" ) ,
new Answer ( AnswerObjectModel . KLIMA , "Klima" ) ,
new Answer ( AnswerObjectModel . ADAPTER , "Adapter" ) ,
new Answer ( AnswerObjectModel . MASINA_ZA_VES , "Veš mašina" ) } ) ,
new Question ( "5. Šta možemo ugraditi na radijatore da nam pomogne smanjiti troškove grijanja za 7-15%?" , new int [ ] { 1 , 3 } ,
new Answer [ ] {
new Answer ( AnswerObjectModel . TERMOSTAT_25 , "Termostat" ) ,
new Answer ( AnswerObjectModel . PREKIDAC_ZA_SVJETLO , "Prekidač za svjetlo" ) ,
new Answer ( AnswerObjectModel . PROFESOR_ATOM_10 , "Profesor Atom +10" ) ,
new Answer ( AnswerObjectModel . ADAPTER , "Adapter" ) } ) ,
2017-05-20 16:43:03 +03:00
new Question ( "6. Ako je vani temperatura 33°C, koja je optimalna temperatura u kući? " , new int [ ] { 4 } ,
2017-05-20 11:23:09 +03:00
new Answer [ ] {
2017-05-20 16:43:03 +03:00
new Answer ( AnswerObjectModel . KUCICA_17 , "Kućica 17°C" ) ,
new Answer ( AnswerObjectModel . KUCICA_22 , "Kućica 22°C" ) ,
new Answer ( AnswerObjectModel . KUCICA_33 , "Kućica 33°C" ) ,
new Answer ( AnswerObjectModel . KUCICA_26 , "Kućica 26°C" ) } ) ,
2017-05-20 11:23:09 +03:00
new Question ( "7. Kakvim načinom pranja posuđa, i uz koji uređaj od navedenih, trošimo 60% manje električne energije i do 85% manje vode?" , new int [ ] { 2 , 3 } ,
new Answer [ ] {
new Answer ( AnswerObjectModel . RUCNO_PRANJE_SUDJA , "Ručno pranje suđa" ) ,
new Answer ( AnswerObjectModel . MASINA_ZA_SUDJE , "Pranje u mašini za suđe" ) ,
new Answer ( AnswerObjectModel . PROFESOR_ATOM_10 , "Profesor Atom +10" ) ,
new Answer ( AnswerObjectModel . STRIK , "Štrik" ) } ) ,
new Question ( "8. Koji uređaj u «stand by» načinu rada troši i do 24% energije u odnosu na potrošnju energije kada je upaljen?" , new int [ ] { 4 } ,
new Answer [ ] {
new Answer ( AnswerObjectModel . RADIJATOR , "Radijator" ) ,
new Answer ( AnswerObjectModel . VENTILATOR , "Ventilator" ) ,
new Answer ( AnswerObjectModel . BICIKLO , "Biciklo" ) ,
new Answer ( AnswerObjectModel . TELEVIZOR , "Televizor" ) } ) ,
new Question ( "9. Jednom godišnje stručna osoba treba provjeriti prohodnost čega? Loša prohodnost doprinosi većoj potrošnji energije za grijanje." , new int [ ] { 1 } ,
new Answer [ ] {
new Answer ( AnswerObjectModel . DIMNJAK , "Dimnjak" ) ,
new Answer ( AnswerObjectModel . AUTO , "Auto" ) ,
new Answer ( AnswerObjectModel . NOVI_PROZOR , "Prozor" ) ,
new Answer ( AnswerObjectModel . UPALJENA_CESMA , "Česma sa vodom" ) } ) ,
new Question ( "10. Uvijek odaberite program s najnižom temperaturom vode koji još uvijek obezbjeđuje dobar kvalitet pranja, za šta od navedenog? " , new int [ ] { 1 , 4 } ,
new Answer [ ] {
new Answer ( AnswerObjectModel . PROFESOR_ATOM_10 , "Profesor Atom +10" ) ,
new Answer ( AnswerObjectModel . STRIK , "Štrik" ) ,
new Answer ( AnswerObjectModel . RUCNO_PRANJE_VESA , "Pranje na ruke" ) ,
new Answer ( AnswerObjectModel . MASINA_ZA_VES , "Mašina za veš" ) } )
} ;
// Positions for answers 1, 2, 3 and 4
private Vector3 [ ] answerPositions = new Vector3 [ ]
{
new Vector3 ( - 10 , 10 , - 5 ) ,
new Vector3 ( - 10 , 5 , - 7 ) ,
new Vector3 ( 10 , 5 , - 7 ) ,
new Vector3 ( 10 , 10 , - 5 )
2017-05-18 22:10:17 +03:00
} ;
2017-05-20 11:23:09 +03:00
private Vector3 answerScale = new Vector3 ( 0.15f , 0.15f , 0.15f ) ;
2017-05-19 22:38:58 +03:00
/// <summary>
/// Use this for initialization
/// </summary>
2017-05-17 14:11:01 +02:00
void Start ( ) {
selectedAnswers = new List < int > ( ) ;
2017-05-20 11:23:09 +03:00
answersHaloEffects = new List < GameObject > ( ) ;
answers = new List < GameObject > ( ) ;
2017-05-17 15:40:49 +02:00
counterValue = counterInitialValue ;
2017-05-20 11:23:09 +03:00
InstantiateAnswers ( ) ;
InstantiateHaloPrefabs ( ) ;
2017-05-17 14:11:01 +02:00
UpdateScene ( ) ;
UpdateCounter ( ) ;
UpdateScore ( ) ;
btnNextQuestion . GetComponent < Button > ( ) . onClick . AddListener ( LoadNextQuestion ) ;
}
2017-05-18 22:10:17 +03:00
2017-05-19 22:38:58 +03:00
/// <summary>
/// // Update is called once per frame
/// </summary>
2017-05-17 14:11:01 +02:00
void Update ( )
{
if ( counterValue > 0 )
{
2017-05-19 19:46:08 +03:00
if ( ! counterDisplayAnswersStarted )
{
counterValue - = Time . deltaTime ;
UpdateCounter ( ) ;
}
2017-05-17 14:11:01 +02:00
}
2017-05-17 15:40:49 +02:00
else
2017-05-20 18:29:26 +03:00
{
if ( questionIdx = = questions . Count )
SceneManager . LoadScene ( "EntryScene" ) ;
else
LoadNextQuestion ( ) ;
}
2017-05-18 22:10:17 +03:00
if ( counterDisplayAnswersValue > 0 & & counterDisplayAnswersStarted )
counterDisplayAnswersValue - = Time . deltaTime ;
else
{
2017-05-20 18:29:26 +03:00
if ( questionIdx = = questions . Count )
SceneManager . LoadScene ( "EntryScene" ) ;
else
{
UpdateScene ( ) ;
counterDisplayAnswersStarted = false ;
}
2017-05-18 22:10:17 +03:00
}
2017-05-19 22:38:58 +03:00
// Select answers event handler
2017-05-17 14:11:01 +02:00
if ( Input . GetMouseButtonDown ( 0 ) )
{
Ray ray = Camera . main . ScreenPointToRay ( Input . mousePosition ) ;
RaycastHit hit ;
if ( Physics . Raycast ( ray , out hit , 100 ) )
{
2017-05-19 19:46:08 +03:00
if ( counterDisplayAnswersStarted )
return ;
2017-05-17 14:11:01 +02:00
Debug . Log ( hit . transform . gameObject . name ) ;
2017-05-19 22:38:58 +03:00
// answerArrayIdx: [1, 40]
int answerArrayIdx = GetAnswerIdx ( hit . transform . gameObject . name ) ;
// answerIdx: [1, 4]
int answerIdx = answerArrayIdx - numberOfAnswers * questionIdx ;
// Answer not selected - select it
2017-05-17 14:11:01 +02:00
if ( ! selectedAnswers . Contains ( answerIdx ) )
2017-05-19 22:38:58 +03:00
{
SetGlowEffect ( answerArrayIdx , true ) ;
2017-05-17 14:11:01 +02:00
selectedAnswers . Add ( answerIdx ) ;
2017-05-19 22:38:58 +03:00
}
// Answer selected - unselect it
2017-05-18 22:10:17 +03:00
else
2017-05-19 22:38:58 +03:00
{
SetGlowEffect ( answerArrayIdx , false ) ;
2017-05-18 22:10:17 +03:00
selectedAnswers . Remove ( answerIdx ) ;
2017-05-19 22:38:58 +03:00
}
2017-05-17 14:11:01 +02:00
}
}
}
2017-05-20 11:23:09 +03:00
/// <summary>
/// Adds Halo prefabs to all answers
/// </summary>
private void InstantiateHaloPrefabs ( )
{
for ( int i = 0 ; i < answers . Count ( ) ; i + + )
{
GameObject answerPrefab = Instantiate ( haloEffect ) as GameObject ;
answerPrefab . SetActive ( false ) ;
answerPrefab . transform . SetParent ( answers [ i ] . transform , false ) ;
answersHaloEffects . Add ( answerPrefab ) ;
}
}
/// <summary>
/// Instantiates all answer objects
/// </summary>
private void InstantiateAnswers ( )
{
for ( int qIdx = 0 ; qIdx < questions . Count ; + + qIdx )
{
for ( int ansIdx = 0 ; ansIdx < numberOfAnswers ; + + ansIdx )
{
Answer ans = questions [ qIdx ] . getPossibleAnswers ( ) [ ansIdx ] ;
string answerName = "Answer" + ( qIdx * numberOfAnswers + ansIdx + 1 ) . ToString ( ) ;
InstantiateAnswerObject ( answerName , ansIdx , ans . getAnswerModel ( ) , ans . getAnswerCaption ( ) ) ;
}
}
}
/// <summary>
/// Instantiates answer object according to its type and sets its transform
/// </summary>
/// <param name="answerName"></param>
/// <param name="answerIdx"></param>
/// <param name="model"></param>
/// <param name="answerCaption"></param>
private void InstantiateAnswerObject ( string answerName , int answerIdx , AnswerObjectModel model , string answerCaption )
{
GameObject answerGameObject = Instantiate ( answerModels [ ( int ) model ] ) as GameObject ;
answerGameObject . SetActive ( true ) ;
answerGameObject . name = answerName ;
answerGameObject . transform . position = answerPositions [ answerIdx ] ;
answerGameObject . transform . localScale = answerScale ;
answerGameObject . GetComponent < ObjectController > ( ) . modelCaption . text = answerCaption ;
answers . Add ( answerGameObject ) ;
}
2017-05-19 22:38:58 +03:00
/// <summary>
/// Next question btn click event handler
/// </summary>
2017-05-17 14:11:01 +02:00
void LoadNextQuestion ( )
{
2017-05-19 22:38:58 +03:00
if ( counterDisplayAnswersStarted )
return ;
2017-05-17 15:40:49 +02:00
scoreValue + = GetScore ( ) ;
2017-05-20 18:29:26 +03:00
if ( scoreValue < 0 )
scoreValue = 0 ;
2017-05-17 15:40:49 +02:00
UpdateScore ( ) ;
2017-05-17 14:11:01 +02:00
selectedAnswers . Clear ( ) ;
2017-05-19 22:38:58 +03:00
ClearCurrentSceneGlowEffect ( ) ;
2017-05-18 22:10:17 +03:00
counterDisplayAnswersValue = counterDisplayAnswersInitialValue ;
counterDisplayAnswersStarted = true ;
2017-05-19 19:46:08 +03:00
counterValue = counterInitialValue ;
2017-05-18 22:10:17 +03:00
ShowAnswers ( ) ;
2017-05-20 18:29:26 +03:00
questionIdx = questionIdx + 1 ;
Debug . Log ( questionIdx ) ;
2017-05-17 14:11:01 +02:00
}
2017-05-19 22:38:58 +03:00
/// <summary>
/// Updates score value - called from Update() method
/// </summary>
2017-05-17 14:11:01 +02:00
private void UpdateScore ( )
{
2017-05-18 10:29:14 +02:00
scoreText . text = scoreValue . ToString ( ) ;
2017-05-17 14:11:01 +02:00
}
2017-05-19 22:38:58 +03:00
/// <summary>
/// Updates counter value - called from Update() method
/// </summary>
2017-05-17 14:11:01 +02:00
private void UpdateCounter ( )
{
2017-05-18 10:29:14 +02:00
counterText . text = counterValue . ToString ( "f0" ) ;
2017-05-17 14:11:01 +02:00
}
2017-05-19 22:38:58 +03:00
/// <summary>
/// Shows correct answers
/// </summary>
2017-05-18 22:10:17 +03:00
private void ShowAnswers ( )
{
for ( int i = numberOfAnswers * questionIdx ; i < numberOfAnswers * ( questionIdx + 1 ) ; i + + )
{
MarkAnswer ( questions [ questionIdx ] . getCorrectAnswers ( ) . Contains ( i - questionIdx * numberOfAnswers + 1 ) , i ) ;
}
}
2017-05-19 22:38:58 +03:00
/// <summary>
/// Updates scene with new question and related answers
/// </summary>
2017-05-17 14:11:01 +02:00
private void UpdateScene ( )
{
2017-05-18 22:10:17 +03:00
RemoveMarks ( ) ;
2017-05-17 14:11:01 +02:00
// Set new question
questionText . text = questions [ questionIdx ] . getQuestionText ( ) ;
2017-05-19 22:38:58 +03:00
// Set answers for selected question
2017-05-20 11:23:09 +03:00
for ( int i = 0 ; i < answers . Count ; i + + )
2017-05-17 14:11:01 +02:00
{
2017-05-17 15:40:49 +02:00
if ( i > = numberOfAnswers * questionIdx & & i < numberOfAnswers * ( questionIdx + 1 ) )
2017-05-17 14:11:01 +02:00
{
answers [ i ] . SetActive ( true ) ;
}
else
answers [ i ] . SetActive ( false ) ;
}
}
2017-05-19 22:38:58 +03:00
/// <summary>
/// Hides correct/incorrect images for currently shown answers
/// </summary>
2017-05-18 22:10:17 +03:00
private void RemoveMarks ( )
{
2017-05-19 22:38:58 +03:00
for ( int i = 0 ; i < numberOfAnswers ; i + + ) {
int answerIdx = questionIdx * numberOfAnswers + i ;
answers [ answerIdx ] . GetComponent < ObjectController > ( ) . imageCorrect . enabled = false ;
answers [ answerIdx ] . GetComponent < ObjectController > ( ) . imageIncorrect . enabled = false ;
}
}
/// <summary>
/// Sets visibility of correct/incorrect overlay images
/// </summary>
/// <param name="isCorrect"></param>
/// <param name="idx"></param>
private void MarkAnswer ( bool isCorrect , int idx )
{
answers [ idx ] . GetComponent < ObjectController > ( ) . imageCorrect . enabled = isCorrect ;
answers [ idx ] . GetComponent < ObjectController > ( ) . imageIncorrect . enabled = ! isCorrect ;
}
/// <summary>
/// Clears glow from all currently shown answers
/// </summary>
private void ClearCurrentSceneGlowEffect ( )
{
for ( int i = 0 ; i < numberOfAnswers ; i + + )
2017-05-18 22:10:17 +03:00
{
2017-05-19 22:38:58 +03:00
int prefabIdx = questionIdx * numberOfAnswers + i ;
2017-05-20 11:23:09 +03:00
answersHaloEffects [ prefabIdx ] . SetActive ( false ) ;
2017-05-18 22:10:17 +03:00
}
}
2017-05-19 22:38:58 +03:00
/// <summary>
/// Clears/Adds glow from a specific answer GameObject
/// </summary>
/// <param name="prefabIdx"></param>
private void SetGlowEffect ( int prefabIdx , bool showGlowEffect )
{
2017-05-20 11:23:09 +03:00
answersHaloEffects [ prefabIdx - 1 ] . SetActive ( showGlowEffect ) ;
2017-05-19 22:38:58 +03:00
}
2017-05-19 19:46:08 +03:00
/// <summary>
/// Returns answer index (X) from answer's name (AnswerX)
/// </summary>
2017-05-19 22:38:58 +03:00
/// <param name="gameObjName">GameObject's name</param>
2017-05-19 19:46:08 +03:00
/// <returns></returns>
2017-05-17 14:11:01 +02:00
private int GetAnswerIdx ( string gameObjName )
{
string resultString = Regex . Match ( gameObjName , @"\d+" ) . Value ;
return System . Int32 . Parse ( resultString ) ;
}
2017-05-19 19:46:08 +03:00
/// <summary>
/// Returns score for a particular question
/// </summary>
/// <returns></returns>
2017-05-17 15:40:49 +02:00
private int GetScore ( ) {
// Didn't try
if ( selectedAnswers . Count = = 0 )
return scoreTimedOut ;
// Correct answer
2017-05-19 19:46:08 +03:00
if ( IsAnswerCorrect ( selectedAnswers , questions [ questionIdx ] . getCorrectAnswers ( ) ) )
2017-05-17 15:40:49 +02:00
return scoreCorrectAnswer ;
else
return scoreIncorrectAnswer ;
2017-05-17 14:11:01 +02:00
}
2017-05-19 19:46:08 +03:00
/// <summary>
/// Compares selected answers with correct answers
/// </summary>
/// <param name="selectedAnswers">List of selected answers</param>
/// <param name="correctAnswers">Array of correct answers</param>
/// <returns></returns>
private bool IsAnswerCorrect ( List < int > selectedAnswers , int [ ] correctAnswers )
{
HashSet < int > correctAnswersSet = new HashSet < int > ( new List < int > ( correctAnswers ) ) ;
return correctAnswersSet . SetEquals ( selectedAnswers ) ;
}
2017-05-17 14:11:01 +02:00
}