VioletaBabel

48. NPC와의 대화창 만들기 본문

BCA/6. Unity RPG 따라하기
48. NPC와의 대화창 만들기
Beabletoet 2018. 6. 22. 11:33

NPC가 나왔을 떄 특정 키를 누르면 대화창이 나오게 하자.


===

대화창 이미지를 구한다.


스프라이트 에디터에서 녹색 박스를 가운데로 오게 네모를 만든 후 apply하면, width, height를 늘렸을 때 가운데만 늘어나서 테두리를 유지할 수 있다. 겁나 신기하네 진짜



===


Image에 방금 위 방법대로 에디트한 대화창을 넣는다. 그리고 계산하기 귀찮으니 Rect Transform의 pivot을 0,0으로 하겠다.



GameCanvas.cs의 OnGUI 함수에서

ChatDialogBackground라고 GameObject를 받은 후 Position을 0,0으로 한다.

그리고 dialogSize를 코드에서 수동으로 잡아주었다.

(화면의 사이즈가 바뀔 때마다 불린다.)



===


이제 Text를 뿌려야 한다.

Image의 자식으로 만든 후 Pivot은 0.5, 0.5이고 width, height는 인스펙터 상에서는 부모와 똑같이 한다.


그리고 GameCanvas.cs의 OnGUI 함수에서 ChatDialogText라고 만들어 GetComponent한 후 OnGUI에서 똑같이 사이즈를 수동으로 맞춘다.

그리고 추가로 박스의 내부에 글이 떠야하므로 전체적인 사이즈에 1 미만의 특정 값을 곱해 텍스트가 대화창 테두리가 아닌 내부에 오도록 하자.


===


엑셀과 병행으로 사용하여 Json 파일을 만들 것.

우선은 엑셀에서 NPC_DIALOG.csv 파일로 출력하여 에셋 폴더의 Texts 폴더에 넣는다.


0,0,안녕하신가!,0

0,0,힘세고 강한 아침!,0

0,0,만일 내게 물어보면,0

0,0,나는 왈도!,1

1,1,논 좌유의 모미 아냐,0

1,1,쥐금카지 그래와코 아페로도 케속,0

2,1,도움!!!!,0

2,1,도움!!!!!!!!!!,1


===


GameData.cs에서 readNpcText라는 함수를 만들고, 시작할 때 불러준다.

FIleStream을 이용해 위 csv 파일을 불러온다.


그리고 fileSize를 받아와야 하는데, long 자료형으로 저장한다.(이제 오버플로우가 되기 쉽다. int는 4기가 정도 까지.)


StreamReader.ReadToEnd() // 현재 위치부터 스트림 끝까지의 모든 문자를 읽는다.


csv라 ,로 값이 구분되어 있으니 ,와 엔터로 구분해준다.


string.split 함수를 이용하되, char[]가 들어가니 "\r\n".ToCharArray() 를 인수로 넣는다. 그럼 줄바꿈을 기준으로 나눠진다.

그 다음 나눈 애를 또 하나하나 ,를 기준으로 똑같이 split해준다.

그럼 이제 대화를 쭉 저장했다.


===


NpcChatData라는 클래스를 만든다.

ID, chatID, Text, Quest를 저장한다 (Text는 string, 나머지는 int)

이건 csv로 저장한 항목들!



그리고 Dictionary<int, List<NpcChatData>> npcChat 을 하나 만든다.

List<NpcChatData> npcDataList 를 하나 만들어둔다.

그리고 ChatID가 같으면 대화를 계속 npcDataList에 넣어두고, 그렇지 않으면 기존의 npcDataList를 npcChat에 넣은 후 npcDataList를 new한다.



===


NPC를 만들고 주인공을 계속 바라보도록 NpcDir.cs를 만든다.


Update에서 주인공과의 거리를 계산하고, 주인공과의 거리가 일정 범위 안이면 주인공을 바라보게 처리한다.


===


NpcChat.cs를 만든다.

npcID, chatID를 인스펙터로 NPC마다 넣어주고

그에 해당하는 chatList를 받아온다.

그리고 update에서 Getmousebuttondown을 이용해 Input.mousePosition을 Camera.main.screenpointtoray 해주어 Ray형 ray에 담고 RaycastHit에 Physics.RaycastAll하여 담는다.


===

글이 한 글자 씩 뜨게 하는 것은 예전에 해봤으니, 이번엔 글이 자연스레 샤라락 왼쪽부터 나오게 해보자.

그러려면 텍스트를 텍스쳐로 바꿔야 한다.

다 만들어진 텍스트를 한쪽 구성에서 카메라로 촬영하고

촬영한 것을 텍스쳐로 바꿔야 함.


마테리얼과 렌더 텍스쳐를 만들고 마테리얼의 Shader에 Unlit-Transparent 한 후 렌더 텍스쳐를 마테리얼에 넣는다.

그리고 새로운 캔버스(월드 스페이스)를 만들고 거기에 텍스트를 추가한다.

카메라를 만들고 타겟 텍스쳐를 아까 만든 렌더 텍스쳐로 한 후 컬링 마스크를 UI만으로 한다.



Plane도 하나 만들고 Mesh Renderer의 Material에 아까 만든 마테리얼을 넣는다.


===


DialogCanvas.cs를 만들고 text1과 text2라는 GameObject를 만들어 각각 캔버스에 있던 애를 넣어준다.

그리고 GameData.cs에서 DialogCanvas를 찾고 DialogCanvas.cs를 GetComponent한다.


===

글이 한 글자 씩 뜨게 하는 것은 예전에 해봤으니, 이번엔 글이 자연스레 샤라락 왼쪽부터 나오게 해보자.

그러려면 텍스트를 텍스쳐로 바꿔야 한다.

다 만들어진 텍스트를 한쪽 구성에서 카메라로 촬영하고

촬영한 것을 텍스쳐로 바꿔야 함.


마테리얼과 렌더 텍스쳐를 만들고 마테리얼의 Shader에 Unlit-Transparent 한 후 렌더 텍스쳐를 마테리얼에 넣는다.

그리고 새로운 캔버스(월드 스페이스)를 만들고 거기에 텍스트를 추가한다.

카메라를 만들고 타겟 텍스쳐를 아까 만든 렌더 텍스쳐로 한 후 컬링 마스크를 UI만으로 한다.



Plane도 하나 만들고 Mesh Renderer의 Material에 아까 만든 마테리얼을 넣는다.


===


DialogCanvas.cs를 만들고 text1과 text2라는 GameObject를 만들어 각각 캔버스에 있던 애를 넣어준다.

그리고 GameData.cs에서 DialogCanvas를 찾고 DialogCanvas.cs를 GetComponent한다.



대화창 이미지는 어떻게든 잘 연결한 다음(나는


        foreach(GameObject g in Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[])

        {

            if(g.tag.Equals("Dialog"))

            {

                dialogWindows = g;

                break;

            }

        }


로 찾았다).


나머진 다음 주에 계속

'BCA > 6. Unity RPG 따라하기' 카테고리의 다른 글

50. 상점 만들기(2)  (0) 2018.06.27
49. 마스크 & 상점 만들기 (1)  (0) 2018.06.26
46. 데이터 세이브 로드, HP바, EXP바  (0) 2018.06.21
45. 몬스터 공격, 해의 순환  (0) 2018.06.20
44. 몹 움직이기  (0) 2018.06.19
Comments