-
안녕하세요.
오늘은 player와 npc의 상호 작용하는 부분을 올리려고 합니다.
마을에는 각 npc들이 존재하며.
현재 배치할 npc오브젝트의 구현 목록은
마을 주민 / 장로 / 상점 / 교관 / 부상당한 병사
로 총 4명의 npc를 구성할 것입니다.
현재 예상으로는 상점을 제외한 나머지 npc의 동작 구현 목록을 보며
상점의 팝업 기능과 구매/판매 기능을 따로 작성하지 않을까 싶습니다.
이 프로젝트는 단순 튜토리얼을 구현한 것이기에
따로 플레이어의 육성은 없지만,
보스를 소탕하기 전까지의 퀘스트를 NPC인 교관에게 받으며 안내를 받고 있습니다.
또한 NPC와 대화를 하거나 일반 몬스터를 잡을 때 경험치를 주며
퀘스트를 클리어할 때에도 경험치를 받을 수 있습니다.
각 렙에 맞게 스킬의 잠금이 해제됩니다.
(LV.1 때는 아무런 스킬을 사용할 수 없습니다)
그럼 바로 가시죠!!
NPC를 클릭 하면 생길 대화창입니다.
빈 오브젝트에 항목들을 생성하여 관리를 편하게 해 주었고
Panel을 생성하여 대화창이 켜져 있을 경우 클릭되는 것을 막아 주었습니다.
Npc_Name : npc이름 / Npc_Dialog : npc가 할 말
스크립트는. Dialog의 Manager를 새로 생성되어
관리를 하게끔 하였습니다.
싱글톤 패턴인 딱 한 군데 Manager스크립트 밖에 없습니다.
이 Manager 스크립트가 나머지 부 Manager들은 관리해 주는데
정말 잘 사용하고 있습니다.
처음엔 복잡하기도 하고 귀찮았는데, 한번 설정을 해놓으면 부 Manager들을 부르기도 편하고
어디서든 접근이 가능하니.. 배워둔걸 요긴하게 잘 쓰고 있습니다!
ManagerDialog 스크립트입니다.
프레임 / 엔피씨 이름 / 엔피씨 대사를 public으로 선언하여 접근할 수 있게 선언했으며
Dialog_Open의 대화창을 오픈하는 기능을 함수로 만들었습니다.
npc_Name의 text와 npc_Dialog의 text는 받아온 name/dialog로 지정되게 했으며
단순히 프레임을 활성화해주는 코드입니다.
대화창이 동기화되는 스크립트는 각 npc들에게 넣어줬으며
이 스크립트를 보기 전 npc를 클릭하면
DialogOpen 함수가 활성화되는 코드부터 보겠습니다!
당연히? 터치 / 클릭할 시 구현될 동작은 PlayerController에서 구현했습니다.
PlayerController에는 (터치/클릭) 시 이벤트가 발생하는
OnPointerDown를 구현해 놓았습니다.
Ray ray = cam.ScreenPointToRay(eventData.position)
클릭한 지점에 (eventData.position) 레이를 생성하여
맞은 녀석의 transform이 있으면 hit에 저장해 주었었는데요
여기서 맞은 transform의 tag가 NPC 일 때
발생하는 if조건문을 걸어 주었습니다.
Targeting함수와 clickNpc = true입니다.
첫 번째로 주석 처리해놓은 것은 현재 테스트 중인데
멀리서 npc를 클릭하면 player가 자동으로 npc앞으로 가서 대화창이 열리게끔 테스트하고 있습니다.
targeting 함수는 enemy를 클릭할 시 보았었는데 바로 살펴보겠습니다.
clickNpc는 npc를 클릭을 했는지 체크할 불 변수입니다.
targeting 함수에서는 target을 ray에 맞은 오브젝트로 저장을 해 주고
그 tag가 Enemy일시 타게팅이 시각적으로 표현되게 해 주었었죠
이번엔 enemy가 아닌 npc를 클릭할 것이기 때문에
else if로 위의 조건이 아니라면 tag가 NPC 인지 검사를 해주고
조준점(target_Tool)은 비활성화해주며 나머지 구현은 enemy와 비슷한 동작을 해주었습니다.
여기서 obj_Name이 Help가 아니라면 의 조건이 붙었는데
이유는 obj_Name이 Help인 npc는 부상당한 병사로
누워 있는 모습을 연출했습니다.
다른 서있는 npc와 똑같이 구현하면 시각적으로 표현되는 target_Rect의 위치가 맞지 않게 되어서
따로 구현을 했습니다.
부상당한 병사를 연출해 보았습니다. 얼핏 보면 자고 있는 것 같지만.... ㅎㅎ...
나름 무기의 위치와 회전 각도 등 마음에 드는 애니메이션을 찾아 리타게팅으로 적용시켜 봤습니다!
이제 DialogOpen를
이 코드는 PlayerController에서 구현했습니다.
위에 Enemy일 시 Enemy의 hpBar를 동기화시켜주는 조건문이 있었죠?
그 아래 target의 tag가 Npc 일 시의 조건문도 걸어주었습니다.
우선 첫 번째로 target!= null / 타깃이 비어있지 않을 시 실행되어야 합니다.
그리고 target.tag == NPC / 타깃의 태그는 NPC이어야 합니다.
그리고 targetDis <= 2 / 타깃과의 거리가 2 이하이어야 합니다.
(이 조건은 멀리서 npc를 클릭했을 시 켜지기에 거리의 조건을 걸어주었습니다.)
그리고 clickNpc가 true 여야 합니다.
(OnPointerDown에서 clickNpc = true로 지정되었습니다.)
모두 &&으로 이 중 단 하나라도 조건이 맞지 않을 시엔 false가 됩니다.
중복 방지를 위해 clickNpc는 false / 각 NPC의 대화창을 오픈할 NPC_Dialog에 있는
Dialog함수 를실행 시키는 모습입니다.
바로 코드 구현부터 보시면. Npc의 이름을 제어하기 위해 string npc_Name으로 가져오며
대화창의 프레임을 활성화시켜주는 Dialog_Open 함수를 실행시킵니다.
인자로는 npc의 이름과 dialog의 대화 내용과 dialogStep을 넣어 주었는데요
각 npc에게 입혀질 NPC_Dialog스크립트의 선언 변수를 일부 보자면
dialogStep : 대화 진행 단계 / dialog : Npc의 대화 창
대화 창을 배열로 담은 이유는 여러 번 대화를 하기 위함입니다.(클릭/터치 시)
즉 다음 대화를 하기 위해선 dialogStep이 증가/감소하며 그에 따른 대화창이 달라지게 구현을 했는데요
단순히 대화만 필요한 npc는 dialogStep++으로 증가를 시켜 주었으며
각 npc의 tag에 맞게 상황을 구현하였습니다.
각 npc들 중 npc_Name이 Help라면? 의 조건문을 보시자면
dialogStep이 증가하는 건 똑같습니다.
다만 대화창을 한번 열었을 시 dialogStep이 1이 되며
함수를 지연 후 실행시켜주는 Invoke 함수로 HelpDisable 함수를 실행시켜줬습니다.
이 코드는 간단하지만. 10초 뒤 사라지게 하기 위해서 만든 함수입니다.
각 npc들의 조건을 영상으로 찍으려고 했는데 너무 분량이 많아져서..
나눠서 영상 촬영을 하였습니다.
순서는 마을 주민 -> 장로 -> 교관 -> 쓰러진 병사입니다.
-추가-
Panel을 클릭하면 비활성화되는 구현을 EventTrigger에서
Pointer Down으로 구현하였습니다
(터치 / 클릭) 시 발생됩니다.
(길을 알려준 (터치/클릭)을 재 하게 되면 같은 dialog [dialogStep] 실행 +exp 30)
(장로를 찾아보라고 합니다)
(아이템을 건네 준 뒤 착용 +exp 30)
(교관을 찾아보라고 길을 알려줍니다.)
퀘스트 & Level Up 후 스킬 슬롯 해제
(퀘스트를 모두 완료하면 플레이어의 Level이 최소 5가 되게 끔 설계했습니다.)
부상당한 교관이 앞의 보스가 있다고 알려 준 뒤 죽었습니다..
또 다른 죽는 연출보다는 SetActive를 false로 비활성화를 시켜 주어
화면 상 안 보이게 만들어 줬습니다!!
(이런 거 사운드를 추가해서 윽.. 으윽.. 같은 대화하는 듯한 느낌을 주면 좋을 것 같은데.....)각 4명의 (마을 주민 / 장로 / 교관 / 병사) npc들과 상호작용을 하는 부분에 대해 영상으로 보았습니다.
이제 상점 NPC와 BOSS만 클리어하면
플레이어의 튜토리얼은 끝입니다.
이 정도만 해도 유저 분들은 한눈에 감을 잡겠죠?
다양한 스킬이라던가 다양한 연출 등 많이 노력을 해야 할 것 같습니다.
다음 글은 상점 NPC로 찾아오겠습니다!!!
감사합니다.
'유니티 프로젝트 > RPG 듀토리얼' 카테고리의 다른 글
RPG 듀토리얼 15. Npc Store OpenStore (0) 2022.04.26 RPG 듀토리얼 14. Object Pool & item Gold (0) 2022.04.26 RPG 듀토리얼 12. Player Skill (Skill 01 - 03) (0) 2022.04.24 RPG 듀토리얼 11. Player Skill (Skill 00 & Calulate) (0) 2022.04.22 RPG 듀토리얼 10. Player Skill (Casting) (0) 2022.04.22