ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RPG 듀토리얼 13. player & NPC 상호작용
    유니티 프로젝트/RPG 듀토리얼

    안녕하세요.

    오늘은 playernpc의 상호 작용하는 부분을 올리려고 합니다.

     

    마을에는 각 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으로 구현하였습니다

    (터치 / 클릭) 시 발생됩니다.

    마을 주민 00 : 20초

    (길을 알려준 (터치/클릭)을 재 하게 되면 같은 dialog [dialogStep] 실행  +exp 30)

    (장로를 찾아보라고 합니다)

    00 : 33초

     

    (아이템을 건네 준 뒤 착용 +exp 30)

    (교관을 찾아보라고 길을 알려줍니다.)

     

    01 : 20초

    퀘스트 & Level Up 후 스킬 슬롯 해제

    (퀘스트를 모두 완료하면 플레이어의 Level이 최소 5가 되게 끔 설계했습니다.)

    00 : 24초

    부상당한 교관이 앞의 보스가 있다고 알려 준 뒤 죽었습니다..

    또 다른 죽는 연출보다는 SetActive를 false로 비활성화를 시켜 주어

    화면 상 안 보이게 만들어 줬습니다!!

    (이런 거 사운드를 추가해서 윽.. 으윽.. 같은 대화하는 듯한 느낌을 주면 좋을 것 같은데.....)

     

    각 4명의 (마을 주민 / 장로 / 교관 / 병사) npc들과 상호작용을 하는 부분에 대해 영상으로 보았습니다.

    이제 상점 NPC와 BOSS만 클리어하면

    플레이어의 튜토리얼은 끝입니다.

     

    이 정도만 해도 유저 분들은 한눈에 감을 잡겠죠?

    다양한 스킬이라던가 다양한 연출 등 많이 노력을 해야 할 것 같습니다.

     

    다음 글은 상점 NPC로 찾아오겠습니다!!!

     

    감사합니다.

    댓글

김효겸 / Tel. 010-7735-0580 / E-mail. dollzzang2@hanmail.net