✅ 기능
게임에서 가장 중요한 인벤토리 시스템을 구현하고 정리해 보았습니다. 인벤토리 시스템을 이용하여 아이템 관리, 상호작용, 아이템 사용, 스킬 등 게임의 수많은 요소를 인벤토리 시스템, 아이템 시스템을 이용하여 편하게 관리하고 사용할 수 있습니다. 1편에서는 가장 기초가 될 인벤토리 관리자를 정리하였습니다.
게임 자체를 완성한 후(모든 기능을 구현) 요소를 추출하여 순서대로 정리한 글입니다. 스크립트 내부에 관련 없는 클래스가 포함될 수 있습니다. 예) Key Binding을 지원하는 새로운 입력, 커서를 잠그는 UtilityManager
🔨 로드맵
[📌현재 글] 1. 유니티 인벤토리 시스템(1) - 인벤토리 관리자
2. 유니티 인벤토리 시스템(2) - 아이템(ScriptableObject)
3. 유니티 인벤토리 시스템(3) - 아이템 슬롯(인벤토리 슬롯)
5. 유니티 인벤토리 시스템(5) - 아이템 슬롯 관리
✅ 흐름도
✅ 구현
1. InventoryBase
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 인벤토리 베이스로써 인벤토리 슬롯들을 등록시키고 사용할 준비를 완료한다.
/// 추상클래스로 작성하여 인벤토리 베이스 자체적으로 인스턴스 할 수 없게 한다.
/// </summary>
abstract public class InventoryBase : MonoBehaviour
{
[SerializeField] protected GameObject mInventoryBase; // Inventory 최상위 부모(활성/비활성 목적)
[SerializeField] protected GameObject mInventorySlotsParent; // Slot들을 담을 부모 게임오브젝트
/// <summary>
/// 인벤토리 베이스를 초기화 시킨다.
/// </summary>
protected void Awake()
{
if (mInventoryBase.activeSelf)
{
mInventoryBase.SetActive(false);
}
mSlots = mInventorySlotsParent.GetComponentsInChildren<InventorySlot>();
}
}
인벤토리가 되어 내부에 인벤토리 슬롯을 갖추고, 아이템을 저장하고 관리할 인벤토리 베이스입니다.
abstract public class InventoryBase : MonoBehaviour
- 인벤토리가 여러 개(필자는 일반 인벤토리, 장비 인벤토리로 구현)로 구현하고자 추상클래스로 정의하였습니다.
[SerializeField] protected GameObject mInventoryBase; // Inventory 최상위 부모(활성/비활성 목적)
- 인벤토리 기능을 구현할 오브젝트의 최상위 부모 GameObject입니다.
- 하이어라키에서 이 GameObject를 활성화/비활성화(SetActive)하여 UI를 보여주도록 하였습니다.
[SerializeField] protected GameObject mInventorySlotsParent; // Slot들을 담을 부모 게임오브젝트
- 하이어라키 구조에서 하위 자식 오브젝트에 인벤토리 슬롯을 넣어 관리하도록 하였습니다.
- 씬을 로드하면 하위에 있는 모든 자식들을 가져와 인벤토리를 초기화합니다.
mSlots = mInventorySlotsParent.GetComponentsInChildren<InventorySlot>();
- 인벤토리 슬롯의 부모의 하위 자식들 중 InventorySlot을 모두 가져옵니다.
- [여기]에서 InventorySlot에 대한 구현을 확인할 수 있습니다.
2. InventoryMain
using UnityEngine;
/// <summary>
/// 여러 아이템을 담을 가장 기본적인 인벤토리
/// </summary>
public class InventoryMain : InventoryBase
{
public static bool IsInventoryActive = false; // 인벤토리 활성화 되었는가?
new void Awake()
{
base.Awake();
}
void Update()
{
TryOpenInventory();
}
/// <summary>
/// 인벤토리를 I키를 눌러 열거나 닫는다.
/// </summary>
private void TryOpenInventory()
{
//옵션이 켜져있는경우 비활성화
if (GameMenuManager.IsOptionActive) { return; }
if (Input.GetKeyDown(KeyManager.Instance.GetKeyCode("Inventory")))
{
if (!IsInventoryActive)
OpenInventory();
else
CloseInventory();
}
}
/// <summary>
/// 인벤토리를 연다.
/// </summary>
private void OpenInventory()
{
mInventoryBase.SetActive(true);
IsInventoryActive = true;
//커서 활성화
UtilityManager.UnlockCursor();
}
/// <summary>
/// 인벤토리를 닫는다.
/// </summary>
public void CloseInventory()
{
mInventoryBase.SetActive(false);
IsInventoryActive = false;
//커서 비활성화
UtilityManager.TryLockCursor();
}
}
- 아이템을 관리하고 보관할 인벤토리 메인입니다.
- 일반적인 인벤토리이며, 아이템 형태로 관리합니다. (소모아이템, 장비아이템, 기타 등)
new void Awake()
- Awake를 사용하여 자기 자신도 초기화하지만 부모 클래스인 InventoryBase도 초기화하기 위해 base.Awake()를 사용합니다.
private void TryOpenInventory()
- 런타임 도중 특정한 키를 눌러 인벤토리를 열고 닫습니다. 필자는 KeyBinding System을 추가로 구현하여 키 설정을 통해 인벤토리를 여는 방법을 적용했으나, 추후에 다룰 예정입니다.
- Input.GetKeyDown(KeyCode....)를 사용해도 무관합니다.
private void OpenInventory()
public void CloseInventory()
- 인벤토리를 열고 닫습니다.
- 인벤토리를 열거나 닫을 때마다 각 함수들이 호출되며 커서를 잠그거나, 잠금해제합니다.
3. EquipmentInventory
using UnityEngine;
using TMPro;
public class EquipmentInventory : InventoryBase
{
public static bool IsInventoryActive = false; // 인벤토리 활성화 되었는가?
[Header("현재 계산된 수치를 표현할 텍스트 라벨들")]
[SerializeField] private TextMeshProUGUI mDamageLabel;
[SerializeField] private TextMeshProUGUI mDefenseLabel;
new private void Awake()
{
base.Awake();
}
private void Update()
{
//옵션이 켜져있는경우 비활성화
if(GameMenuManager.IsOptionActive) { return; }
if (Input.GetKeyDown(KeyManager.Instance.GetKeyCode("Equipment")))
{
if (mInventoryBase.activeInHierarchy)
{
mInventoryBase.SetActive(false);
IsInventoryActive = false;
UtilityManager.TryLockCursor();
}
else
{
mInventoryBase.SetActive(true);
IsInventoryActive = true;
UtilityManager.UnlockCursor();
}
}
}
}
- 장비 인벤토리입니다.
- InventoryMain과 같은 기능을 수행하지만, 목적이 다르기에 분리하였습니다.
- 장비 아이템 관리 (장착, 장착해제, 효과 등)에 특화된 기능을 구현할 목적입니다.
4. 인벤토리 UI 만들기
- 캔버스의 하위에 활성화, 비활성화 목적의 게임오브젝트를 생성합니다.
- InventoryMain을 사용하기 위해 GridLayout을 사용하여 아이템슬롯이 정렬되도록 합니다.
- 인벤토리 슬롯을 자식으로 생성하고, 크기와 위치가 맞도록 GridLayout속성을 조절합니다.
- 아이템 슬롯 한개에는 배경 이미지, 아이템 이미지, 쿨타임 이미지와 아이템의 개수를 보여줄 텍스트 게임오브젝트가 추가로 있습니다.
- 장비 인벤토리를 위한 아이템 슬롯은 GridLayout을 사용하지 않고 이미지에 맞게 배치하였습니다.
5. 씬에 배치하기
- 씬에 매니저와 같이 Inventory System을 생성하여 컴포넌트를 추가하였습니다.
- 컴포넌트의 속성에 최상위 부모와, GridLayout을 사용하는 인벤토리 슬롯들의 부모 오브젝트를 등록하였습니다.
✅ 사용(적용) 예시
'unity game modules' 카테고리의 다른 글
[유니티] 인벤토리 시스템(3) - 아이템 슬롯(인벤토리 슬롯) (0) | 2022.12.26 |
---|---|
[유니티] 인벤토리 시스템(2) - 아이템(ScriptableObject) (0) | 2022.12.26 |
[유니티] 3D World, Sprite Ordering Layer (0) | 2022.12.23 |
[유니티] 애니메이션 랜덤으로 재생하기(StateMachineBehaviour) (0) | 2022.11.23 |
[유니티] 편리하게 소리를 담당하는 사운드 매니저 구현 (0) | 2022.11.21 |