🧠 오늘의 핵심 정리
- AddListener로 버튼 이벤트를 코드에서 유연하게 관리
- ScriptableObject(ItemData)로 아이템 데이터를 분리해서 관리
- Scroll View + 슬롯 프리팹 기반 인벤토리 UI 구성 + 스크롤 초기화
- 아이템 상세 패널 구현 : 사용/장착/해제/삭제 버튼 + 상태에 따른 버튼 분기
🎒 41일차 : UI로 인벤토리 & 스탯창 만들기
게임을 만들다 보면 결국 UI를 만질 일이 생기게 됩니다. (도망 못 감)
그래서 오늘은 “언젠가 해야지…” 하던 인벤토리창 / 스탯창을 UI로 직접 만들어보는 시간을 가졌습니다.
🧷 AddListener 활용 : 버튼 이벤트를 코드로 정리
버튼 이벤트를 처리할 때 AddListener를 사용하니까 확실히 코드가 깔끔해지고, 버튼 기능을 유연하게 붙일 수 있어서 정말 편했습니다.
특히 오늘은 “아이템 상세 패널”처럼 버튼이 여러 개인 UI가 있었는데, 인스펙터에서 하나씩 연결하는 것보다 코드로 한 번에 정리하는 게 훨씬 관리하기 좋았어요.
UIStatus.cs : 버튼 클릭 시 스탯 텍스트 갱신
void Awake()
{
openButton.onClick.AddListener(OpenClicked);
closeButton.onClick.AddListener(CloseClicked);
}
public void SetCharacterStat()
{
attackTXT.text = GameManager.Instance.player.Attack.ToString();
defenseTXT.text = GameManager.Instance.player.Defense.ToString();
healthTXT.text = GameManager.Instance.player.Health.ToString();
criticalTXT.text = GameManager.Instance.player.Critical.ToString();
}
private void OpenClicked()
{
UIManager.Instance.OpenStatus();
SetCharacterStat();
}
메인 메뉴 텍스트(직업/이름/레벨/설명/골드)도 같은 방식으로 버튼 눌렀을 때 갱신되게 처리했습니다.
📦 ScriptableObject로 아이템 관리
아이템 데이터를 ScriptableObject(ItemData)로 만들었습니다.
데이터 관리가 직관적이고 재사용성도 높아서 “아이템 종류가 많아지면 많아질수록 이게 진짜 빛을 보겠다” 싶었어요.
ItemData.cs : 아이템 타입/스택/효과까지 확장
[CreateAssetMenu(fileName ="NewItem",menuName ="Item")]
public class ItemData : ScriptableObject
{
public string _name;
public Sprite icon;
public int count;
public string description;
```
public bool canStack;
public int maxStackAmount;
public ItemType type;
public ItemDataConsumable[] consumables;
public ItemDataEquipableType[] equipables;
```
}
그리고 런타임에서는 Item 클래스로 감싸서 현재 개수(CurrentCount), 장착 여부(IsEquipped) 같은 상태를 따로 관리했습니다.
🧾 Scroll View 첫 사용 : 슬롯 프리팹으로 인벤토리 UI 구성
이번에 처음으로 Scroll View를 사용해봤습니다.
인벤토리 아이템이 많아질 때 스크롤로 깔끔하게 보여줄 수 있어서 앞으로 UI 확장할 때 진짜 유용하겠다고 느꼈어요.
UIInventory.cs : 캐릭터 인벤토리를 기준으로 슬롯 생성
public void InitInventoryUI(Character character)
{
foreach(var slot in slots)
{
Destroy(slot.gameObject);
}
slots.Clear();
```
foreach(var item in character.Inventory)
{
UISlot newSlot = Instantiate(slotPrefab, slotParent);
newSlot.SetItem(item);
slots.Add(newSlot);
}
```
}
public void ResetScrollRect()
{
scrollRect.normalizedPosition = new Vector2(0,1);
}
닫을 때 스크롤 위치가 이상하게 남는 게 거슬려서, 닫는 순간 normalizedPosition으로 스크롤을 위로 다시 올리는 것도 같이 처리했습니다.
🔍 아이템 상세 패널 : 사용/장착/해제/삭제 버튼 분기
그리고 오늘 제일 “게임 UI 같다” 싶었던 부분이 아이템 상세 패널이었습니다.
슬롯을 클릭하면 상세 패널이 열리고, 아이템 타입에 따라 사용/장착/해제 버튼이 달라지게 구현했습니다.
UISlot.cs : 슬롯 버튼 클릭 시 상세 패널 열기
void Awake()
{
openButton.onClick.AddListener(() =>
UIManager.Instance.OpenInventoryDetail(currentItem));
}
UIManager.cs : 상세 패널 열기 + 버튼 리스너 동적 연결
public void OpenInventoryDetail(Item item)
{
_panel.SetActive(true);
RefreshUIInventoryDetail(item);
```
useButton.onClick.RemoveAllListeners();
equipButton.onClick.RemoveAllListeners();
unEquipButton.onClick.RemoveAllListeners();
deleteButton.onClick.RemoveAllListeners();
useButton.onClick.AddListener(() => {
GameManager.Instance.player.EatItem(item);
RefreshUIInventoryDetail(item);
});
equipButton.onClick.AddListener(() => {
GameManager.Instance.player.EquipItem(item);
RefreshUIInventoryDetail(item);
});
unEquipButton.onClick.AddListener(() => {
GameManager.Instance.player.UnEquipItem(item);
RefreshUIInventoryDetail(item);
});
deleteButton.onClick.AddListener(() => {
DeleteItem(item);
CloseInventoryDetail();
});
// 타입에 따른 버튼 분기
if (item.Data.type == ItemType.Equipable)
{
useButton.gameObject.SetActive(false);
equipButton.gameObject.SetActive(!item.IsEquipped);
unEquipButton.gameObject.SetActive(item.IsEquipped);
}
else
{
useButton.gameObject.SetActive(true);
equipButton.gameObject.SetActive(false);
unEquipButton.gameObject.SetActive(false);
}
```
}
그리고 장착 아이템은 슬롯에 개수 대신 E를 표시하게 해서 “장착중”이란 걸 한눈에 볼 수 있게 했습니다.
UISlot.cs : 장착 표시(E)
itemCountTXT.text = currentItem.CurrentCount > 1 ? currentItem.CurrentCount.ToString() : "";
if (currentItem.Data.type == ItemType.Equipable && currentItem.IsEquipped)
{
itemCountTXT.text = "E";
}
📌 느낀 점
오늘 해보면서 다시 느낀 건, 이벤트 처리(AddListener), 데이터 관리(ScriptableObject), UI 컴포넌트(Scroll View) 이 세 가지가 진짜 중요하다는 점이었습니다.
특히 인벤토리는 “기능만 되는 것”보다 보기도 편하고, 조작도 자연스럽게 만들어야 진짜 게임 같아지는 것 같아요.
앞으로도 이런 기능들을 적극적으로 활용해서, UI가 늘어나도 관리 가능한 구조로 계속 만들어봐야겠습니다.
🔜 내일 할 일
- 아이템 상세 패널 UI/UX 다듬기 (버튼 활성/비활성, 텍스트 표시 예외처리)
- 스탯창과 인벤토리 연동 정리 (장착/해제 시 스탯 자동 갱신)
'내일배움캠프 본캠프' 카테고리의 다른 글
| [내일배움캠프 43일차 TIL] 프로토타입 1일차 '팀 편성' (0) | 2025.11.28 |
|---|---|
| [내일배움캠프 42일차 TIL] 인벤토리 완성 (0) | 2025.11.27 |
| [내일배움캠프 40일차 TIL] UI과제 (0) | 2025.11.24 |
| [내일배움캠프 39일차 TIL] 팀 프로젝트 발표 (0) | 2025.11.21 |
| [내일배움캠프 38일차 TIL] 펫 시스템 (0) | 2025.11.20 |