본문 바로가기
TIL

[멋쟁이사자처럼 부트캠프 TIL 회고] 유니티 게임개발 3기 53일차 퀴즈게임 제작2

by HYttt 2025. 2. 13.

퀴즈게임 제작

퀴즈 카드 보여주는 방식 변경

  • 세번째 카드를 오브젝트풀에 반환하는 형태로 변경
private void ChangeQuizCard()
    {
        var temp = _firstQuizCardObject; //임시로 저장
        _firstQuizCardObject = _secondQuizCardObject;
        _secondQuizCardObject = ObjectPool.Instance.GetObject(); //새로 만들기

        SetQuizCardPosition(_firstQuizCardObject, 0); //순서 지정
        SetQuizCardPosition(_secondQuizCardObject, 1);
        
        ObjectPool.Instance.ReturnObject(temp); //반환
    }

퀴즈 데이터를 읽어와 카드에 표시 

  • csv파일로 되어있는 퀴즈 데이터 읽어오기

 

using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;

public static class QuizDataController
{
    static string ROW_SEPARATOR = @"\r\n|\n\r|\n|\r";
    private static string COL_SEPARATOR = @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))";
    private static char[] TRIM_CHARS = {'\"'};
    public static List<QuizData> LoadQuizData(int stageIndex)
    {
        var fileName = "QuizData-" + stageIndex;
        
        TextAsset quizDataAsset = Resources.Load(fileName) as TextAsset;
        
        var lines = Regex.Split(quizDataAsset.text, ROW_SEPARATOR);

        var quizDataList = new List<QuizData>();
        
        for (var i = 1; i < lines.Length; i++)
        {
            var values = Regex.Split(lines[i], COL_SEPARATOR);
            QuizData quizData = new QuizData();
            
            for(var j = 0; j < values.Length; j++)
            {
                var value = values[j];
                value = value.TrimStart(TRIM_CHARS).TrimEnd(TRIM_CHARS).Replace("\\", "");
                
                switch (j)
                {
                    case 0:
                        quizData.question = value;
                        break;
                    case 1:
                        quizData.description = value;
                        break;
                    case 2:
                        quizData.type = int.Parse(value);
                        break;
                    case 3:
                        quizData.answer = int.Parse(value);
                        break;
                    case 4:
                        quizData.firstOption = value;
                        break;
                    case 5:
                        quizData.secondOption = value;
                        break;
                    case 6:
                        quizData.thirdOption = value;
                        break;
                }
            }
            quizDataList.Add(quizData);
        }
        return quizDataList;
    }
}
  • 읽어온 데이터는 QuizData 구조체에 저장하여 List로 반환
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public struct QuizData
{
    public string question;
    public string description;
    public int type;
    public int answer;
    public string firstOption;
    public string secondOption;
    public string thirdOption;
}

public class QuizCardController : MonoBehaviour
{
    [SerializeField] private TMP_Text questionText;
    [SerializeField] private TMP_Text descriptionText;
    [SerializeField] private Button[] optionButtons;
    
    public delegate void OnQuizCardDelegate(int cardIndex);
    private OnQuizCardDelegate onCompleted;
    
    public void SetQuiz(QuizData quizData, OnQuizCardDelegate onCompleted)
    {
        // 1. 퀴즈
        // 2. 설명
        // 3. 타입 (0: OX퀴즈, 1: 보기 3개 객관식)
        // 4. 정답
        // 5. 보기 (1,2,3)
        
        // 퀴즈 데이터 표현
        questionText.text = quizData.question;
        //descriptionText.text = quizData.description;
        var firstButtonText = optionButtons[0].GetComponentInChildren<TMP_Text>();
        firstButtonText.text = quizData.firstOption;
        var secondButtonText = optionButtons[1].GetComponentInChildren<TMP_Text>();
        secondButtonText.text = quizData.secondOption;
        var thirdButtonText = optionButtons[2].GetComponentInChildren<TMP_Text>();
        thirdButtonText.text = quizData.thirdOption;
        
        this.onCompleted = onCompleted;
    }
}
  • 이후 InitQuizCards( )에서 초기화
using System;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;

public class GamePanelController : MonoBehaviour
{
    [SerializeField] private GameObject quizCardPrefab;
    [SerializeField] private Transform quizCardParent;
    

    private GameObject _firstQuizCardObject;
    private GameObject _secondQuizCardObject;
    
    private List<QuizData> _quizDataList;

    private int _lastGeneratedQuizIndex;
    
    private const int MAX_QUIZ__COUNT = 10;
    private void Start()
    {
        // test
        _quizDataList = QuizDataController.LoadQuizData(0);
        
        InitQuizCards();
    }
    
    private void InitQuizCards()
    {
        _firstQuizCardObject = ObjectPool.Instance.GetObject();
        _firstQuizCardObject.GetComponent<QuizCardController>().SetQuiz(_quizDataList[0], OnCompletedQuiz);
        
        _secondQuizCardObject = ObjectPool.Instance.GetObject();
        _secondQuizCardObject.GetComponent<QuizCardController>().SetQuiz(_quizDataList[1], OnCompletedQuiz);
        
        SetQuizCardPosition(_firstQuizCardObject, 0);
        SetQuizCardPosition(_secondQuizCardObject, 1);
        
        _lastGeneratedQuizIndex = 1;
    }
    
    private void OnCompletedQuiz(int cardIndex)
    {
        // 퀴즈 카드가 완료되었을 때 호출되는 함수
    }
    
    private void SetQuizCardPosition(GameObject quizCardObject, int index)
    {
        var quizCardTransform = quizCardObject.GetComponent<RectTransform>();
        if (index == 0)
        {
            quizCardTransform.anchoredPosition = new Vector2(0, 0);    
            quizCardTransform.localScale = Vector3.one;
            quizCardTransform.SetAsLastSibling(); 
        }
        if (index == 1)
        {
            quizCardTransform.anchoredPosition = new Vector2(0, 160);
            quizCardTransform.localScale = Vector3.one * 0.9f;
            quizCardTransform.SetAsFirstSibling(); 
        }
    }

    private void ChangeQuizCard()
    {
        if (_lastGeneratedQuizIndex >= MAX_QUIZ__COUNT) return;
        
        var temp = _firstQuizCardObject; //임시로 저장
        _firstQuizCardObject = _secondQuizCardObject;
        _secondQuizCardObject = ObjectPool.Instance.GetObject(); //새로 만들기

        if (_lastGeneratedQuizIndex < _quizDataList.Count -1)
        {
            _lastGeneratedQuizIndex++;
            _secondQuizCardObject.GetComponent<QuizCardController>().SetQuiz(_quizDataList[_lastGeneratedQuizIndex], OnCompletedQuiz);
        }
        
        SetQuizCardPosition(_firstQuizCardObject, 0); //순서 지정
        SetQuizCardPosition(_secondQuizCardObject, 1);
        
        ObjectPool.Instance.ReturnObject(temp); //반환
    }

    public void OnClickNextButton()
    {
        ChangeQuizCard();
    }
    
}

퀴즈 카드 순서대로 표시

  • 마지막으로 로드된 카드의 인덱스를 int변수로 추적
  • 카드 교환될 때마다 2번쨰 카드에 데이터 입력
private void ChangeQuizCard()
    {
        if (_lastGeneratedQuizIndex >= MAX_QUIZ__COUNT) return;
        
        var temp = _firstQuizCardObject; //임시로 저장
        _firstQuizCardObject = _secondQuizCardObject;
        _secondQuizCardObject = ObjectPool.Instance.GetObject(); //새로 만들기

        if (_lastGeneratedQuizIndex < _quizDataList.Count -1)
        {
            _lastGeneratedQuizIndex++;
            _secondQuizCardObject.GetComponent<QuizCardController>().SetQuiz(_quizDataList[_lastGeneratedQuizIndex], OnCompletedQuiz);
        }
        
        SetQuizCardPosition(_firstQuizCardObject, 0); //순서 지정
        SetQuizCardPosition(_secondQuizCardObject, 1);
        
        ObjectPool.Instance.ReturnObject(temp); //반환
    }