[unity]- 2d 탑다운 [ 퀘스트 ]
>QuestManager생성
QuestData도 만들어준다. 이는 npc번호와 퀘스트이름을 저장해준다.
GameManager에 QuestManager 끌여다놓아야한다. (코드에 선언 후에)
>코드 수정, 구현
-QuestData 스크립트-
처음에 QuestData뒤에 :MonoBehaviour를 제거해주었다. 쓸필요가없어서.
public class QuestData
{
public string questName;
public int[] npcId;
public QuestData(string name, int[] npc) {
questName = name;
npcId = npc;
}
}
스크립트 이름이랑 같이 선언하면 이는 생성자로 함수가 실행되면 바로 같이 실행된다.
-----QuestManager스크립트------
public int questId;
public int questActionIndex;
public GameObject[] questObject;
Dictionary<int, QuestData> questList;
퀘스트 id와 퀘스트인덱스, 퀘스트 진행가능한 오브젝트를 선언해주고,
퀘스트list도 딕셔너리로 선언한다.
-Awake함수
private void Awake()
{
questList = new Dictionary<int, QuestData>();
GenerateData();
}
딕셔너리를 초기화해주고 새로운 함수도 실행해준다.
-GenerateData 함수 -퀘스트list 추가
void GenerateData()
{
questList.Add(10,new QuestData("마을사람들과의 이야기 나누기 "
,new int[] {1000,2000}));
questList.Add(20, new QuestData("루도의 동전 찾아주기."
, new int[] { 5000, 2000 }));
questList.Add(30, new QuestData("퀘스트 올클리어"
, new int[] { 0}));
}
questList 딕셔너리에 퀘스트id랑 퀘스트 이름, npc id를 추가해준다.
-GetQuestTalkIndex 함수 : 퀘스트 id+ 퀘스트행동인덱스
public int GetQuestTalkIndex(int id)
{
return questId+ questActionIndex;
}
-CheckQuest 함수
public string CheckQuest(int id)
{
//next talk target
if (id == questList[questId].npcId[questActionIndex])
questActionIndex++;
//control quest object
ControlObject();
//퀘스트 대화순서가 끝에 도달했을때 퀘스트 번호 증가
if (questActionIndex == questList[questId].npcId.Length)
NextQuest();
//quest name
return questList[questId].questName;
}
만약 매개변수의 오브젝트의 id가 questList의 questId번째인덱스의 npcId의 questActionIndex번째 인덱스의 npcId와 같다면 questActionIndex를 늘려주어 다음 npc를 가리키도록한다.
ControlObject함수는 동전 관련 함수이다.
그리고 만약 quesetActionIndex가 npcId 배열의 길이와 같으면 퀘스트가 끝난것이므로 다음 퀘스트로 넘어가줘야한다.
questList의 questId의 퀘스트이름을 반환해준다. (Debug창에서 보기위해서)
- CheckQuest 오버로딩하기
public string CheckQuest()
{
return questList[questId].questName;
}
오버로딩은 똑같은 함수 이름을 사용할수있다. 매개변수는 달라야한다.
그냥 퀘스트 이름만 리턴한다.
-NextQuest함수
void NextQuest()
{
questId += 10;
questActionIndex = 0;
}
다음 퀘스트로 넘어가기위해 questId를 10 늘려준다( 왜냐면 퀘스트 번호를 10,20,30으로 10씩 띄워놨기 때문)
그리고 questActionIndex도 초기화해줘야한다.
-ControlObject 함수
void ControlObject()
{
switch (questId)
{
case 10:
if (questActionIndex == 2)
questObject[0].SetActive(true);
break;
case 20:
if (questActionIndex == 1)
questObject[0].SetActive(false);
break;
}
}
이는 동전 관련 함수인데, 동전관련 퀘스트가 떴을때만 보이게 해주는 함수이다.
questId가 10일때 2번째 퀘스트를 마치고나서 동전 퀘스트를 할당받으므로 이때 동전이 보이게 해줘야한다.
questId가 20일때 동전을 클릭하면 1이되므로 먹으면 사라지게한다.
-TalkManager 수정,추가
//quest talk
talkData.Add(10+ 1000, new string[] { "어서 와.:0",
"이 마을에 놀라운 전설이 있다는데:1"," 오른쪽 호수 쪽에 루도가 알려줄꺼야.:0" });
talkData.Add(11 + 2000, new string[] { "여어.:1",
"이 호수의 전설을 들으러 온거야?:0"
," 그럼 일 좀 하나 해주면 좋을텐데...:1",
" 내 집 근처에 떨어진 동전 좀 주워줬으면 해.:2"});
talkData.Add(20 + 1000, new string[] { "루도의 동전?:1",
"돈을 흘리고 다니면 못쓰지!:3"
," 나중에 루도에게 한마디 해야겠어.:3"});
talkData.Add(20 + 2000, new string[] {
" 찾으면 꼭 좀 가져다줘.:1"});
talkData.Add(20 + 5000, new string[] {
"근처에서 동전을 찾았다."});
talkData.Add(21 + 2000, new string[] {
"엇, 찾아줘서 고마워,:2"});
questActionIndex가 추가 되는것을 생각하여 11이나 21같은 값을 정해서 더해줘야한다.
-GetTalk 함수
public string GetTalk(int id,int talkIndex)
{
//예외처리
if (!talkData.ContainsKey(id)) //key가 있냐 없냐 확인
{
//퀘스트 맨 처음 대사마저 없을때
//기본 대사를 가지고 온다.
if (!talkData.ContainsKey(id - id % 10)) {
return GetTalk(id - id % 100, talkIndex);
}//반환값있는 재귀함수는 return써주기
//id가 없으면 퀘스트 대화순서를 제거 후 재탐색
//퀘스트 맨 처음 대사 가지고 온다.
else
return GetTalk(id - id % 10,talkIndex);
}
if (talkIndex == talkData[id].Length)
return null;
else
return talkData[id][talkIndex];
}
예외처리를 해줘야한다. 하지 않으면 올바르지 않은 값으로 대화를 걸었을때 오류가 생겨서 멈춘다.
Key로 id값이 없을때 예외처리를 해준다.
id-id%10은 만약 1021이 id라 하면 1021-1=1020이다. 만약 1020이라는 id가 Key에 없으면
물체( 100,200)이므로 id-id%100이 id로 주어진다. 다시 GetTalk를 실행한다.
id값이 있을때는 talkIndex가 talkData의 id번의 대화 갯수랑 같으면 끝난것이므로 null값을 가진다.
아니면 그 대화를 반환한다.
-----GameManager ----
public QuestManager questManager;
QuestManager를 선언해준다.
-Start 함수
private void Start()
{
Debug.Log(questManager.CheckQuest());
}
questManager에서 퀘스트 이름을 반환해주는 함수를 콘솔창에 뜨게 한다.
-Talk 함수
//set talk data
int questTalkIndex= questManager.GetQuestTalkIndex(id);
string talkData=talkManager.GetTalk(id+ questTalkIndex, talkIndex);
//end talk
if (talkData == null)
{
isAction=false;
talkIndex = 0;
Debug.Log(questManager.CheckQuest(id));
return; //강제종료 역할
}
questTalkIndex는 questId+ questActionIndex로 저장된다.
talkData는 GetTalk를 불러와서 대화를 저장한다.
만약 대화가 없다면 행동을 끝내고 index를 0으로 해주고 퀘스트이름을 콘솔창에 뜨게 해준뒤 대화를 강제종료시킨다.