ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RPG 듀토리얼 15. Npc Store OpenStore
    유니티 프로젝트/RPG 듀토리얼

    안녕하세요.

    이번 글에서는 상점 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"으로도 찾을 수 있긴 한데, 보통 전 가끔 플레이어를 찾을 때? 빼고는 다른 용도로 사용해 본 적이 없습니다.)

    00 : 15초

    상점 팝업 기능을 짧은 영상으로 보시면서 오늘은 이만 물러나겠습니다.

    (BAG하고 STORE 현재 맵과 잘 어울리지 않나요? 나름 엄청난 고민과 고민을......)

     

    오늘도 정말 감사합니다.

    댓글

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