zyeon's 작심삼일 코딩 공부
대화·퀘스트 시스템 - (4) 퀘스트 본문
퀘스트의 이름과 그 퀘스트에 관련된 NPC ID 배열을 저장하는
퀘스트 데이터 클래스를 작성한다.
public class QuestData
{
public string questName = "";
public int[] npcId = { };
public QuestData(string name, int[] id)
{
this.questName = name;
this.npcId = id;
}
}
블로그에서는 글이 너무 길어져 생략하지만
퀘스트 매니저도 호출하기 쉽게 싱글톤으로 작성해주었다.
public class QuestManager : MonoBehaviour
{
public int questId;
public int questActionIndex;
[SerializeField] GameObject[] m_questObject;
Dictionary<int, QuestData> m_questList;
/* 싱글톤 코드 생략... */
private void Awake()
{
/* 싱글톤 코드 생략... */
GenerateQuest();
}
void GenerateQuest()
{
m_questList = new Dictionary<int, QuestData>();
m_questList.Add(10, new QuestData("공주님의 부탁", new int[] { 1000, 1000 }));
m_questList.Add(20, new QuestData("린다에게 조언 듣기", new int[] { 3000, 2000, 1000 }));
m_questList.Add(30, new QuestData("공주님에게 별 갖다주기", new int[] { 1000 }));
m_questList.Add(40, new QuestData("첫번 째 퀘스트 끝", new int[] { 0 }));
if (!PlayerPrefs.HasKey("QuestID"))
PlayerPrefs.SetInt("QuestID", questId);
else
questId = PlayerPrefs.GetInt("QuestID");
}
Awake()에 퀘스트 생성 함수를 호출하여, 씬이 로드될 때 퀘스트가 생성된다.
퀘스트 리스트는 Quest ID 와 QuestData 객체를 매핑하는 역할을 해준다.
예를 들어 m_questList.Add(10, new QuestData("공주님의 부탁", new int[] { 1000, 1000 })); 와 같은 퀘스트는
- 퀘스트 ID : 10
- 퀘스트 이름: 공주님의 부탁
- NPC ID가 1000인 NPC와 두 번 상호 작용한다.
이와 같은 내용의 퀘스트이다.
퀘스트는 10 →20 →30 →40과 같이 퀘스트 id에 따라 진행시킬 것 이기 때문에
퀘스트 진행 상황을 PlayerPrefs에 저장해 주었다.
public void CheckQuest(int id)
{
questId = PlayerPrefs.GetInt("QuestID");
//다음 대화로
if (id == m_questList[questId].npcId[questActionIndex] && QuestCondition())
{
questActionIndex++;
}
ControlObject();
//퀘스트 마지막 대화 후 다음 퀘스트로
if (questActionIndex == m_questList[questId].npcId.Length && QuestCondition())
NextQuest();
}
CheckQuest()는 특정 NPC와 상호작용할 때 퀘스트의 진행 상황을 확인하고, 퀘스트 완료 시
NextQuest()를 이용해 다음 퀘스트로 넘겨준다.
▼NextQuest()
void NextQuest()
{
questId += 10;
PlayerPrefs.SetInt("QuestID", questId);
questActionIndex = 0;
}
퀘스트 ID가 10 단위로 구분되어 있기 때문에
퀘스트 ID를 10 더해주어 다음 퀘스트로 넘겨준다.
퀘스트 진행상황을 유지할 수 있게 PlayerPrefs에 저장해준다.
퀘스트 진행 단계를 다시 0으로 초기화 해주어 다음 퀘스트를 처음부터 시작할 수 있게 해준다.
현재 상호작용한 NPC와 현재 퀘스트 단계의 NPC가 일치하고,
QuestCondition()로 다른 퀘스트 시작 조건이 충족되는지 확인 되면
퀘스트의 다음 단계로 넘어간다.
▼ QuestCondition()
//퀘스트 시작 조건
bool QuestCondition()
{
bool result = true;
switch (questId) //퀘스트 성공 조건이 있는 부분 작성
{
case 10:
break;
case 20:
if (questActionIndex == 3 && PlayerPrefs.GetInt("Star") < 5)
result = false;
break;
case 30:
break;
}
if (result == false) questActionIndex--;
return result;
}
만약 퀘스트 시작 조건에 충족하지 못한다면
퀘스트 진행 상황을 원래대로 되돌린다.
ControlObject()로 퀘스트와 관련된 오브젝트를 제어한다.
▼ ControlObject()
void ControlObject()
{
switch (questId)
{
case 10:
break;
case 20:
if (questActionIndex == 2) //린다랑 대화 끝났을 때 숲으로 가는 길을 열어준다.
{
m_questObject[0].SetActive(false); //0: roadblock
PlayerPrefs.SetInt("RoadBlock", 1);
}
break;
case 30:
if (questActionIndex == 1) //공주랑 대화가 끝나면
{
int star = PlayerPrefs.GetInt("Star") - 5;
PlayerPrefs.SetInt("Star", star);
int hp = PlayerPrefs.GetInt("FullHP") + 1;
PlayerPrefs.SetInt("FullHP", hp);
GameObject.Find("Canvas").GetComponent<StarTextMain>().SetStar();
}
break;
case 40:
break;
}
}
퀘스트를 무사히 완료할 시 일어나는 변화들을 관리한다.
public int GetQuestDialogIndex(int id)
{
return questId + questActionIndex;
}
대사 출력 시 필요한 퀘스트 ID를 받아오기 위한 함수도 작성해주면 퀘스트 끝.
'unity' 카테고리의 다른 글
대화·퀘스트 시스템 - (3) 대화문 출력 (0) | 2024.09.12 |
---|---|
대화·퀘스트 시스템 - (2) 대화문 저장 (0) | 2024.09.12 |
대화·퀘스트 시스템 - (1) NPC 설정, 플레이어 레이캐스트 (4) | 2024.09.12 |
플레이어 상태, 상태 머신 (0) | 2024.09.12 |
2.5D 게임에서 캐릭터 이동 구현 (0) | 2024.08.28 |