일단 탈착을 위해서는 별도의 UI창이 필요합니다. Inventory_Panel에서 EquipmentSlots라는 빈 오브젝트를 생성합시다.
그리고 본래 있는 Slot Prefab을 복사하여 EquipmentSlot이란 프리팹을 만듭시다. UI예시는 다음과 같습니다.
| 슬롯 | 위치 | 장착아이템 |
|---|---|---|
| 1 | 얼굴 | 호흡기 등 |
| 2 | 몸 | 수트 |
| 3 | 등 | 제트팩, 가방 등 |
현재 아이템이 탈착이 가능한 아이템인지 아닌지를 판별해야합니다.
// ItemData.cs
public EquipmentType equipmentType;
public enum EquipmentType
{
None,
Face,
Body,
Back
}
인벤토리 창에서 탈착이 가능한 아이템을 더블클릭하면 아이템이 옮겨지게 할 겁니다.
PlayerState에 새 배열 변수가 필요할 겁니다.
// PlayerState.cs
// 에디터의 Inspector에서 배열 3개 추가
public ItemInstance[] equipmentItems;
public void AddEquipmentItem(ItemInstance item)
{
switch (item.itemData.equipmentType)
{
case EquipmentType.Face:
SetEquipmentItems(0, item);
break;
case EquipmentType.Body:
SetEquipmentItems(1, item);
break;
case EquipmentType.Back:
SetEquipmentItems(2, item);
break;
default:
break;
}
}
private void SetEquipmentItems(int index, ItemInstance item)
{
if (equipmentItems[index])
{
inventory.AddItem(equipmentItems[index]);
uiManager.UpdateItemUI();
}
equipmentItems[index] = item;
}
기존 함수에 추가합니다.
// UIManager.cs
public void OnInventorySlotDoubleClick(int slotIndex)
{
if (!inventory.items[slotIndex]) return;
// 장착 아이템
if (inventory.items[slotIndex].itemData.equipmentType != EquipmentType.None)
{
playerState.AddEquipmentItem(inventory.items[slotIndex]);
inventory.RemoveItem(slotIndex);
UpdateItemUI();
return;
}
// 물, 식량, 힐팩 아이템
if (inventory.items[slotIndex].itemData.itemType == ItemType.BioState && inventory.UseItem(slotIndex))
{
Destroy(inventory.items[slotIndex].gameObject);
inventory.RemoveItem(slotIndex);
UpdateItemUI();
return;
}
}
EquipmentSlot 스크립트를 추가하여 관리합시다.
// EquipmentSlot.cs
using UnityEngine;
using UnityEngine.UI;
public class EquipmentSlot : MonoBehaviour
{
// 비어있을때 아이콘
[SerializeField] private Sprite slotImage;
// 현재 슬롯의 타입 (얼굴, 몸, 등)
public EquipmentType equipmentType;
// 변경할 아이템 이미지 위치
private Image itemIcon;
private void Start()
{
itemIcon = transform.Find("ItemIcon").GetComponent<Image>();
}
public void SetEquipmentSlot(ItemInstance item)
{
if (item)
{
itemIcon.sprite = item.itemData.icon;
itemIcon.color = Color.white;
}
else
{
itemIcon.sprite = slotImage;
itemIcon.color = new Color(255, 255, 255, 100);
}
}
}
인벤토리에서 더블클릭하면 이동한 것이 보이게 합시다.
// UIManager.cs
public GameObject equipmentSlotPanel;
private EquipmentSlot[] equipmentSlots;
void Start()
{
if (equipmentSlotPanel != null)
{
equipmentSlots = equipmentSlotPanel.GetComponentsInChildren<EquipmentSlot>();
}
}
// 이 함수를 OnInventorySlotDoubleClick 함수에 추가!
private void UpdateEquipmentUI(EquipmentType type, ItemInstance item)
{
switch(type)
{
case EquipmentType.Face:
equipmentSlots[0].SetEquipmentSlot(item);
break;
case EquipmentType.Body:
equipmentSlots[1].SetEquipmentSlot(item);
break;
case EquipmentType.Back:
equipmentSlots[2].SetEquipmentSlot(item);
playerItemHandler.SetBackSocket(item);
break;
default:
break;
}
}
// PlayerItemHandler.cs
public void SetBackSocket(ItemInstance item)
{
if (!item || item == backSocketItem) return;
backSocketItem = item;
SetHoldingItem(backSocketItem, backSocket);
// 더블클릭한 아이템이 현재 들고 있는 아이템일 경우에만 null로 할당!
if (item == currentItem)
{
currentItem = null;
}
}
탈착형 아이템은 착용을 하고 떼어내는 것도 필요합니다. 그것은 EquipmentSlot에서 더블클릭 이벤트로 합시다.
// EquipmentSlot.cs
public void OnPointerClick(PointerEventData eventData)
{
if (eventData.clickCount == 2)
{
RemoveItem(equipmentType);
}
}
public void SetEquipmentSlot(ItemInstance item)
{
if (item)
{
itemIcon.sprite = item.itemData.icon;
itemIcon.color = Color.white;
}
else
{
itemIcon.sprite = slotImage;
itemIcon.color = new Color(1, 1, 1, 0.5f);
}
}
private void RemoveItem(EquipmentType type)
{
int index = -1;
if (type == EquipmentType.Face) index = 0;
else if (type == EquipmentType.Body) index = 1;
else if (type == EquipmentType.Back) index = 2;
else return;
if (!inventory.AddItem(playerState.equipmentItems[index]) || !playerItemHandler) return;
if (index == 0) return;
else if (index == 1) return;
else if (index == 2) playerItemHandler.ClearBackSocketHolding();
playerState.equipmentItems[index] = null;
SetEquipmentSlot(null);
uiManager.UpdateItemUI();
}
// PlayerItemHandler.cs
public void ClearBackSocketHolding()
{
if (!backSocketItem) return;
backSocketItem.gameObject.SetActive(false);
backSocketItem = null;
}
인벤토리를 열고 장착하면 UI가 뜨며 아이템을 사용할 수 있는 모습입니다.
만약에 연료가 0%가 된다면 아이템은 사용할 수 없으며, 충전이 되어 있는 연료통으로 갈아끼울시 다시 사용 가능합니다. (모듈형)
다음 글에서는: