-
안녕하세요.
이번 글에서는 상점 npc에 대해 다룰 예정입니다.
구현 동작 목록을 보자면
1. 상점 NPC를 클릭하면 상점이 열리게 됩니다.
2. 상점에 있는 아이템을 구매 및 판매를 할 수 있습니다.
2가지로 크게 볼 수 있을 것 같습니다.
Store프레임과 Bag프레임입니다.
(그림적 감각은 타고나야 한다고 하던데,, 살짝 감각이 있는 것 같기도 하고..)네 STORE프레임은 간단한 이미지로 만들었으며
각 슬롯과 슬롯의 자식으로 텍스트를 붙여주었습니다.
NPC들의 퀘스트 창과 똑같이 Panel을 만들어
Panel을 터치/클릭 시 비활성화를 되게 만들었으며
경계 선을 지점으로 위쪽은 StoreFrame이 비활성화되며
상점 npc를 터치 / 클릭 시 StoreFrame과 BagFrame이 같이 켜지게 구현할 것이기 때문에
BagFrame도 비활성화를 해 주었습니다.
이후 효과음과 / Bag 안에서 이루어질 활성화된 오브젝트들을 모두 꺼 주었습니다.
(Panel 터치 / 클릭 시 )
활성화는 PlayerController에서 담당하였습니다.
(여기서 진짜 ㅜㅜ 생각해 보면 단순하지만
ray에 충돌체 검사를 하려면 collider가 꼭 필요합니다....)
(왜 안되는지 처음부터 차근차근 보면 될걸 가설병이라 혼자 역추적을 하고 있는....)OnPointerDown (터치/클릭) 시 실행되는 이벤트에서
태그가 Store이면 Targeting함수를 실행되게 해 주었습니다.
target = hit.transform을 해 주었었죠
또한 target_Tool은 비활성화 / target_Rect는 활성화를 해주며
위치를 잡아 주었습니다.
이후
(target!= null && target.tag == "Store" && targetDis <= 2 && clickNpc)
타깃이 비어있지 않을 시
그리고
타깃의 태그가 Store일 시
그리고
targetDis가 2 이하 일 시
그리고
clickNpc가 true일시
&& 연산자로 이 중 하나라도 조건이 맞지 않으면 false로 실행이 안됩니다.
targetDis는 멀리서 클릭했을 시에도 대화창이 뜨는 현상을 방지하기 위해 거리의 제한을 주었고.
clickNpc는 중복 체크 방지용으로 사용됐습니다.
네 여기서
Manager.instance.managerInven.storeFrame.GetComponent <Items_StoreFrame>(). OpenStore()
로 OpenStore로 상점을 여는 기능을 담당했습니다.
(한 번씩 짚고 넘어간 부분들이 있어서 간략하게 진행했습니다.)
이제 OpenStore의 함수 구현 부분을 보겠습니다.
우선 NPC Store에게 아이템 목록을 갖고 있게 해 주었습니다.
GameObject [] 배열로 선언해 주었으며
NPC "Store"의 인스펙터 창입니다.
이후 상점 스크립트는 NPC가 아닌
UI항목으로 만든 상점 Frame에게 넣어 주었습니다.
이렇게 구현한 이유는, 유저가 아이템을 사는 건 Npc Store 한테 사는 것이 지만
실질적으로 아이템을 구매/판매하는 동작은 상점이 담당하기 때문입니다.
상점 프레임에 입혀줄 Items_StoreFrame 스크립트의 선언 변수입니다.
Transform [] slot_saleItems로 슬롯을 받아왔습니다.
(이 슬롯에 npc가 갖고 있는 아이템을 넣어 주어 상점의 슬롯에 아이템을 시각화해줄 것입니다.)
이후 PlayerController에서 실행시켜주는 Items_StoreFrame 스크립트의 OpenStore함수입니다.
(OpenStore 함수는 단순하게 상점 오픈 기능입니다.)
Manager.instance.playerController.target.GetComponent <NPC_Store>(). saleItems
의 코드를 보자면 target(npc Store)이고
NPC_Store의 saleItems는 npcStore가 갖고 있는 아이템이 됩니다.
이후 이를 제어하기 위해 GameObject [] saleItem_Npc를 선언하여 받아 줍니다.
for (int i = 0; i < saleItem_Npc.Length; i++)
for문을 통해 상점의 슬롯에 npcStore가 갖고 있는 아이템을 적용시켜 주는 코드입니다.
여기서 if(saleItem_Npc [i]!= null) 이 코드를 조건을 걸어 준 이유는
상점이 판매할 아이템이 없을 경우를 대비했습니다.
(상인이 아이템이 없을 경우는 현재로선 없겠다만,
이런 거 하나하나 쌓여서 버그를 줄일 수 있다고 들었습니다)네.. 바로 진행하겠습니다.
슬롯과 아이템의 동기화 부분은 간단합니다.
Instantiate(saleItem_Npc [i], slot_saleItems [i])
Instantiate로 인해 saleItem_Npc [i] 아이템을 slot_saleItems [i]에 생성해 줍니다.
이를 제어하기 위해 GameObject obj를 선언해 받아 saleItem_Npc [i] 오브젝트를 받아왔으며
상점에 있는지 체크할 불 변수 inStore는 true
obj의 부모에 접근하여 GetChild(0)의 텍스트를 아이템의 가격으로 저장해 줬습니다.
우선 생성될 아이템을 인스펙터 창으로 보겠습니다.
StoreFrame을 인스펙터 창에서 본모습이며
slot_1에만 아이템이 들어가 있습니다.
나머지 slot들은 Text밖에 없으며
아이템이 있건 없건 GetChild(0)는 Text(가격표시)가 됩니다.
inStore는 Item_Action 스크립트에서 아이템이 상점에 있는지 없는지 체크할 불 변수였습니다.
클릭/터치 시 실행되는 이벤트 OnPointerDown에서
inBag과 inStore로 나뉘어 if문의 조건문을 구현했었습니다.
이 inStore가 true인 상태 일 시에는
단순 아이템의 정보만 가져옵니다.
(inBag일 때 실행되는 ReleaseTime는 필요가 없습니다)
이후 마지막으로 gameObject를 SetActive = true로 활성화해서
상점 창을 팝업 시키는 OpenStore 함수를 완성시켰습니다.
그 당연한? 얘기는 아니지만 npcStore와 Slot_saleItems의 슬롯에 해당 오브젝트가 무엇인지 넣어서 알려 줘야 합니다.
(GameObject.Find 같은 함수로 하이어 라키 창에 있는 오브젝트의 "Name"으로도 찾을 수 있긴 한데, 보통 전 가끔 플레이어를 찾을 때? 빼고는 다른 용도로 사용해 본 적이 없습니다.)
상점 팝업 기능을 짧은 영상으로 보시면서 오늘은 이만 물러나겠습니다.
(BAG하고 STORE 현재 맵과 잘 어울리지 않나요? 나름 엄청난 고민과 고민을......)오늘도 정말 감사합니다.
'유니티 프로젝트 > RPG 듀토리얼' 카테고리의 다른 글
RPG 듀토리얼 17. BOSS!!! 01 / 02 (Attack) (0) 2022.04.27 RPG 듀토리얼 16. Store buy and sell (0) 2022.04.26 RPG 듀토리얼 14. Object Pool & item Gold (0) 2022.04.26 RPG 듀토리얼 13. player & NPC 상호작용 (0) 2022.04.25 RPG 듀토리얼 12. Player Skill (Skill 01 - 03) (0) 2022.04.24