스탠다드반 꾸준실습 2주차
Q1. 싱글톤 기능 구현하기
❓ 싱글톤(Singleton)이란 특정 클래스의 인스턴스가 애플리케이션 내에서 하나만 존재하도록 보장하는 패턴으로,
어디에서나 접근가능한 객체를 생성해서 편하게 접근하기 위해 사용합니다.
심판처럼 게임의 흐름을 관리하는 객체라고 생각하면 마음 편하실 거에요!
스파르타 RPG에서는 퀘스트들을 관리하는 QuestManager이라는 클래스가 있습니다.
이 클래스를 구현하기 위해 싱글톤(Singleton) 패턴을 활용할 것입니다.
[구현사항 1]
싱글톤 패턴을 구현할 때, 정적(static) 필드를 활용하여 구현합니다.
아래 스켈레톤 코드의 QuestManager에 대한 QuestManager 타입 정적 필드 instance를 private으로 정의하세요.
[구현사항 2]
프로퍼티는 값을 읽거나(get) 쓸(set) 때 동작하는 메소드(getter/setter)를 편하게 활용할 수 있도록 정의된 기능입니다. QuestManager 클래스에 정적 프로퍼티 Instance를 정의하고, 아래와 같은 상황에 대응하세요.
값을 읽을 때 instance가 null인지 확인하고 null이라면 QuestManager 타입을 가진 컴포넌트를 찾아서 넣으세요(FindObjectOfType<T>).
위의 과정에도 불구하고 null이라면 새로운 게임오브젝트를 생성하세요(new GameObject() / AddComponent<T>).
[구현사항 3]
싱글톤은 그 이름에서 유추할 수 있듯이 한 개의 인스턴스가 유일하게 존재해야 합니다.
Awake()에서 인스턴스가 하나만 존재할 수 있도록 검사하는 로직을 추가하세요.
Q2. List / Dictionary를 활용한 오브젝트 풀 구현하기
스파르타 RPG는 화살이 빗발치는 전장 안에서 진행되는 게임입니다. 다만, 화살이 아무리 많아도 동시에 300개가 넘게 존재하지 않는다는 것을 천재프로그래머인 당신은 알게 되었습니다. 또, 몬스터도 동시에 50개 이상 존재하지 않는다는 것을 알게 되었죠.
[구현사항 1]
강의에서 스치듯이 본 오브젝트 풀을 List를 통해 구현하고자 합니다.
기본적으로 300개의 게임오브젝트를 생성하고, Get / Release를 구현하세요.
(Get : 오브젝트 풀에서 비활성인 게임오브젝트를 가져오는 행위, Release: 활성중인 게임오브젝트를 비활성으로 두는 행위)
[구현사항 2]
화살과 몬스터 각각을 오브젝트 풀로 관리하다보니 불편함을 느낀 당신은, 오브젝트 풀을 string인 키를 통해 접근하기로 합니다.
예를 들어 pools["Monster"]를 통해 몬스터 풀에 접근할 수 있는 것이죠.
[구현사항 1]의 오브젝트 풀을 해당 내용에 맞게 수정해보세요.
using UnityEngine;
using System.Collections.Generic;
public class ObjectPool : MonoBehaviour
{
public GameObject prefab;
private List<GameObject> pool = new List<GameObject>();
public int poolSize = 300;
void Start()
{
// 미리 poolSize만큼 게임오브젝트를 생성한다.
}
public GameObject Get()
{
// 꺼져있는 게임오브젝트를 찾아 active한 상태로 변경하고 return 한다.
}
public void Release(GameObject obj)
{
// 게임오브젝트를 deactive한다.
}
}
Q3. Scriptable Object를 활용하여 데이터 구조화하기
스파르타 RPG에서는 Scriptable Object를 통해 퀘스트의 데이터를 저장합니다.
Q1의 QuestManager를 활용하여 퀘스트를 관리하는 시스템의 기본적인 구현을 해봅시다.
[구현사항 1]
퀘스트의 정보를 저장하는 스크립터블 오브젝트 QuestDataSO를 정의하세요. QuestDataSO에는 아래와 같은 필드를 정의하세요.
- QuestName - 퀘스트의 이름
- QuestRequiredLevel - 퀘스트의 최소레벨
- QuestNPC - 퀘스트를 주는 NPC의 id (int)
- QuestPrerequisites - 선행 퀘스트의 id들의 리스트
[구현사항 2]
QuestDataSO를 상속받는 MonsterQuestDataSO와 EncounterQuestDataSO를 정의하고,
각각에 필드를 한 개씩 정의한 뒤(본인이 임의로 넣어보면 됩니다.) 이를 생성해봅시다.
[구현사항 3]
Q1에서 정의한 QuestManager에 퀘스트 데이터들을 다양하게 생성하여 Quests 필드를 정의하여 인스펙터창에 넣고, 시작하면 모든 퀘스트의 이름과 최소레벨을 아래와 같이 출력하세요.
- Quest 1 - 유니티 마스터가 되는 길 (최소 레벨 70)
- Quest 2 - 스파르타에 입성했다 (최소 레벨 10)
(단, 코드처리된 부분은 목록으로 출력되면서 변하는 부분임.)
[선택 구현사항]
[구현사항 3]의 Quest의 정보를 출력할 때 퀘스트의 내용을 MonsterQuestDataSO인지,
EncounterQuestDataSO인지에 따라 다르게 출력하세요. 아래는 예시입니다.
- Quest 1 - 유니티 마스터가 되는 길 (최소 레벨 70)
안혜린 매니저님의 꾸준과제를 50마리 소탕
- Quest 2 - 스파르타에 입성했다 (최소 레벨 10)
한효승 매니저님과 대화하기
(단, 이탤릭체된 부분은 상속받은 클래스의 하위 클래스에 따라 달라지는 내용임.)
오브젝트 풀을 List를 통해 구현하고자 합니다.
기본적으로 300개의 게임오브젝트를 생성하고, Get / Release를 구현하세요.
Queue :
# Queue 선언방법
public Queue<int> intQueue;
// 큐는 FIFO(First-in First-out) 구조로서, 줄을 서는 것처럼 가장 오래 줄 선(enqueue) 객체가
가장 먼저 빠져 나올(dequeue) 수 있는 구조
오브젝트 풀 기본구조
퀘스트의 정보를 저장하는 스크립터블 오브젝트 QuestDataSO를 정의하세요.
스크립터블 오브젝트
[Unity] 유니티(C#) 자료구조 - Queue, Stack
Queue 흔히 FIFO로 알고있는 큐를 유니티에서 알아보자 유니티에서는 제네릭으로 타입을 지정하는 Queue로 타입을 지정하는데 System.Collections.Generic 네임스페이스에 포함되어 있다 FIFO는 쉽게 말해
velog.io
Scriptable Object 이해하기 (10강)
FileName : 기본 Object생성시 만들어지는 파일이름
MenuName : Create시 보이는 메뉴 순서
Order : Asset 폴더의 순서 - 번호
[CreateAssetMenu(fileName ="DefaultDataSO", menuName = "QuestManager/QuestDataSO", order =0)]
[CreateAssetMenu(fileName = "DefaultDataSO", menuName = "QuestManager/QuestDataSO/MonsterQuestDataSO", order = 1)]
[CreateAssetMenu(fileName = "DefaultDataSO", menuName = "QuestManager/QuestDataSO/EncounterQuestDataSO", order = 2)]
QuestData를 상속받아 MonsterQuest , EncounterQuest 클래스생성후, 내부 변수 값 활용