안녕하세요 '언리얼로 만들어보는 RPG'의 필자입니다. 저번글에 이어서 이번글에서는 만들어둔 Item클래스를 이용해 무기 블루프린트를 하나 만들어보고 아직 줍는기능을 구현하지 않았으니 인벤토리에 임시로 데이터를 넣어두고 장착과 해제를 해보겠습니다.
그러고보니 저번글에서 빼먹은 부분이 하나 있었습니다. 장비UI를 만들었으면 당연히 해야하는 과정이다보니 무심코 지나가버렸네요. GameUI에 장비UI를 위한 변수를 마련해주고 바인드 시켜주면 됩니다.
GameUI.h
<장비UI를 위한 변수선언과 Bind를 위한 meta설정>
GameUI.cpp
<Player포인터를 채워주고 초기화시킨다>
BasicSword(블루프린트 에디터)
필자의 무기는 SkeletalMesh이기 때문에 SkeletalIem클래스를 기반으로 BasicSword라는 블루프린트를 만들어 주었습니다. 필요한 Mesh를 지정해준다음 ItemData를 채워줍니다. 여기서 가장 중요한 부분은 ItemClass 변수를 잘 매칭해서 넣어주셔야 한다는것입니다. 그래야 장비를 착용했을때 엉뚱한게 나타나지 않게 되니까요.
필자는 장비 교체의 테스트를 위해서 두개의 무기를 만들었습니다. 참고하시면 좋을 것 같네요.
BpP(블루프린트 에디터)
<테스트를 위해 준비한 무기 두개>
이제 장비 장착과 해제를 위한 준비는 다 됐군요. 앞으로 해야할건 장비를 사용하면 지정해준 ItemClass를 통해서 World상에 스폰시켜주어 Mannequin에 마련해둔 Weapon소켓에 붙이는 것 과 해제하면 인벤토리에 다시 들어가는걸 해주면 됩니다.
Slot.cpp
<초기화 부분에 Type이 Gear인 경우를 추가해준다>
<갱신할때 Type이 Gear인 경우를 추가해준다>
<Slot 사용시 Type이 Gear인 경우를 추가해준다>
<이제 우클릭하면 조건없이 사용하자>
Slot UI쪽에서 해줘야할 준비는 이정도가 다인거 같습니다. 이제 장비를 사용했을때 스폰시키고 장착시키는 것만 하면 되겠군요.
InGameData.cpp(ItemData)
필자가 보기에도 좀 지저분해보이는건 인정합니다. 아직 코드가 완벽히 정리된건 아니기도 하고 필자가 현재 설계한 부분이 좀 마음에 안드는 게 있는데 이걸 건드리자니 너무 오래걸릴 것 같아 임시로 처리해둔 것입니다.
변명은 이정도면 충분한 것 같으니 코드에 대한 설명이 좀 필요할 것 같네요. Slot UI 쪽에서 조건없이 FItemData::Use 함수를 부를 수 있도록 하였으니 해당 함수쪽에서 예외처리를 해줘야 했습니다. ItemType이 None이거나 Equipment인 경우는 비어있기 때문에 return시켜줍니다.
inven변수는 현재 플레이어의 인벤토리에서 비어있는칸을 찾아내서 저장해주는 변수입니다. 밑줄친 함수가 해당 역할을 하는데 설명하는걸 깜빡했군요. 이건 차례 차례 순서대로 이야기 하겠습니다.
isTakeoff변수는 장비를 착용하는건지 해제하는건지에 따라서 아이템의 Count수를 조절하도록 한것인데 먼저 조금 이야기하자면 이미 착용중인 장비와 같은 부위의 장비를 사용할때 교체하는 부분에서 문제가 생겨서 저런 처리를 해준 것 입니다.
index변수는 ItemType을 이용해서 장비일경우 배열에 접근할때 사용하려 만들어둔 변수입니다. 이덕분에 for문을 쓰거나 if문을 잔뜩쓰는 방법은 피할 수 있게됐습니다.
이제 테두리친 1번박스부터 살펴보도록 하겠습니다. 아이템을 사용했는데 해당 아이템 정보를 가지고 있던 Slot의 Type을 확인해서 Gear인경우 장비를 해제하는것입니다. 해제하면 인벤토리에 들어가야하니 어느 위치에 넣어야 할지 알아야 합니다. 그때 이용하는 함수가 FindEmptySlot입니다.
PlayerBase.cpp
위함수는 들어온 ItemData의 Type을 이용해서 비어있는 자리를 찾아줍니다. 포션같은 경우는 한칸에 여러개가 있을 수 있기때문에 예외 처리를 따로 해주어야합니다.
이후에는 별거 없습니다. 인벤토리의 Slot이 들고있던 ItemData로부터 1:1로 연결되어있는 Slot의 주소를 새롭게 넣어줄 Data에 대입해주고 해당 Data를 인벤토리에 다시 넣어주면 끝입니다. 물론 이후에 끼고있던 장비를 Destroy시켜주는것과 새롭게 넣은 인벤토리를 갱신해주는것 또한 잊으면 안됩니다.
다음은 테두리친 2번박스를 확인할 시간입니다. 인벤토리에 있는 장비를 사용했는데 이미 같은부위의 장비가 착용되어있다면 교체를 해주어야 합니다. 필자가 여기서 이상하게 시간을 많이 투자하게 됐는데 isTakeoff변수가 이를 위해서 만들어진것 입니다.
이미 착용중인 장비로부터 ItemData를 받아서 원래 인벤토리에 있는 장비와 교체가 되어야 하는데 이럴 경우 사용한것은 인벤토리의 Slot이기 때문에 갱신을 하긴 하되 Count수가 줄어들면 안되는 문제가 있습니다. 그래서 이미 착용중일경우 isTakeoff가 true로 변하여 그런일을 막아주는 것 입니다.
이외에는 평범하게 장비를 바꿔주고 인벤토리의 UI를 갱신해주기만 하면되는데 장비를 소켓에 붙여주는 역할은 밑줄친 GearUp 함수에서 해줍니다.
PlayerBase.cpp
<아이템 Type에 따라 소켓을 정해서 붙여준다>
여기까지 작업을 했다면 이제 장비를 착용하고 해제하고 교체할 준비가 완벽히 끝났습니다. 사실 Drag&Drop에 대한것도 처리해야겠지만 그건 나중을 기약하기로 했습니다.
<흡족한 결과>
이렇게 또 하나의 관문을 통과했습니다. 다음엔 전투하겠다고 설레발 안치고 스킬이나 만들예정입니다. 그럼 이번글은 여기서 마무리하도록하고 다음에 뵙겠습니다.
'프로그래밍 > 언리얼' 카테고리의 다른 글
언리얼로 만들어보는 RPG - 스킬창 구현(2) (0) | 2019.04.04 |
---|---|
언리얼로 만들어보는 RPG - 스킬창 구현(1) (0) | 2019.03.27 |
언리얼로 만들어보는 RPG - 장비창 구현(1) (0) | 2019.03.06 |
언리얼로 만들어보는 RPG - 퀵슬롯 구현(3) (0) | 2019.02.23 |
언리얼로 만들어보는 RPG - 퀵슬롯 구현(2) (0) | 2019.02.22 |