인벤토리 제작은 유니티 6.1을 사용하고 있습니다.
인벤토리에서 사용될 아이템을 만들어 보겠습니다.
하나의 아이템 구성을 위한 스크립트블 오브젝트입니다.
using UnityEngine;
[CreateAssetMenu(menuName = "ScriptableObjects/Item")]
public class Item : ScriptableObject
{
[Header("아이템 ID")]
public string itemID;
[Header("아이템 이름")]
public string itemName;
[Header("아이템 이미지")]
public Sprite itemImage;
[Header("아이템 판매 가격")]
public long gold;
#if UNITY_EDITOR
private void OnValidate()
{
if (itemID.Length <= 0)
{
itemID = System.Guid.NewGuid().ToString();
}
}
#endif
}
기본 값들은 따로 설명이 필요하진 않겠네요 하단에 UNITY_EDITOR의 경우 itemId의 문자 길이가 0이라면 즉
값이 없을 때 자동으로 생성시켜 줍니다.
itemName이나 다른 곳에 값을 입력하면 자동 생성 됩니다.
이제 아이템을 만들어 보겠습니다.
Item.cs를 저장하시면 유니티의 Project 탭에서 Items라는 폴더를 만드신 후 해당 폴더에서
마우스 오른 버튼으로 Create > ScriptableObjects > Item으로 아이템을 생성해 주시면 됩니다.
샘플로 사용할 아이템 이미지입니다.
아이템의 이름은 blue이며 오른쪽에 해당 아이템의 정보가 입력되어 있습니다.
red 이름을 가진 아이템 정보창입니다.
일단 아이템을 두 개만 사용하겠습니다.
위 이미지처럼 Inventory에 InventoryManager.cs를 만들어 넣습니다.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
public class InventoryManager : MonoBehaviour
{
[Header("인벤토리 슬롯 목록")]
public List<InventorySlot> inventorySlots = new();
[Header("등록될 슬롯의 Parent 목록 : Content")]
[SerializeField] private Transform[] slotParent;
[Header("인벤토리 아이템")]
[SerializeField] GameObject inventoryItem;
private int maxStackedItems = 999;
public bool AddItem(Item item)
{
// 같은 아이템이 있음 겹쳐 준다.
for (int i = 0; i < inventorySlots.Count; i++)
{
var slot = inventorySlots[i];
var itemInSlot = slot.GetComponentInChildren<InventoryItem>();
if (itemInSlot != null &&
itemInSlot.item.itemID == item.itemID &&
itemInSlot.count < maxStackedItems)
{
itemInSlot.count++;
itemInSlot.RefreshCount();
return true;
}
}
// 새로운 아이템이면 빈 슬롯을 찾아 넣어 준다.
for (int i = 0; i < inventorySlots.Count; i++)
{
var slot = inventorySlots[i];
var itemInSlot = slot.GetComponentInChildren<InventoryItem>();
if (itemInSlot == null)
{
CreateNewItem(item, slot);
return true;
}
}
return false;
}
private void CreateNewItem(Item item, InventorySlot slot)
{
var g = Instantiate(inventoryItem);
g.transform.SetParent(slot.transform);
g.transform.localScale = new Vector3(1, 1, 1);
g.SetActive(true);
g.GetComponent<InventoryItem>().InitialiseItem(item);
}
}
InventoryManager에 계속 추가되는 내용들이 있지만 현재는 위에 보이는 코드만
적용시켜 보겠습니다.
Contant A와 B에 들어 있는 Slot을 넣어 주세요
위 이미지처럼 적용시켜 주시면 됩니다.
Inventory 아래에 위치한 Contant A와 Contant B를 넣어 주세요
1부에서 만들었던 프리펩 Item을 여기에 넣어 주시면 됩니다.
인벤토리에 같은 아이템을 넣다 보면 중첩되는 개수가 있을 겁니다.
물론 무한대로 중첩되게 할 수도 있지만 여기에선 999개까지 중첩 후 새로운 Slot에 넣어
주는 방식으로 진행하겠습니다. 이건 사용하시는 분들의 편의에 맞게 고쳐 주시면 되겠네요/
말 그대로 아이템을 인벤토리에 넣어 주는 역할을 하는 곳입니다.
위에서 등록한 InventorySlots의 수량만큼 for문을 돌려 첫 for문에서는 Slot이 아이템을 가지고 있으면서
Add 시키려는 아이템의 id와 현재 Slot에 있는 아이템의 id가 같다면 또한 두 개의 조건이 충족한 상태에서
중첩된 수량이 maxStackedItems 보다 작다면 --> 같은 아이템으로 인식하여
아이템의 count를 1 올려 주며 count Text를 다시 표시하여 true를 return 합니다.
위 조건을 충족 못 했다면 빈 Slot을 찾아 CreateNewItem을 이용해 아이템을 해당 Slot에 생성 후 역시 true를 return 합니다.
만약 모든 조건을 만족 못했다면 즉 같은 아이템도 없으며 빈 슬롯도 없다면 false를 return 합니다.
여기서 true와 false를 return 하는 조건은 해당 조건에 따라 메시지를 출력하기 위함이지만
여기선 따로 구현하지 않겠습니다. 사용하시는 분들이 알맞게 만들어 보시기 바랍니다.
아이템을 새로운 Slot에 배치하기 위해 사용되는 메서드이며 inventoryItem 프리펩을 생성하여
받아온 빈 Slot의 위치에 맞게 inventoryItem을 해당 Slot 아래에 배치합니다.
localScale의 역할은 아이템을 정상적으로 넣었지만 보이지 않는 경우가 있는데 이런 경우
대부분이 Scale 값이 0으로 변해 있어 그렇습니다.
** localScale의 값 대신 g.transform.SetParent(slot.transform, flase) -> flase 값을 주면 기존 프리펩 설정으로
사용할 수도 있습니다. 하지만 Grid Layout Group이나 다른 Layout Group이 있을 경우
다른 결과 값이 혹 나올 수 있으니 flase 적용 후 제대로 작동한다고 해도 localScale을 1로 변경해 주시는게 더 좋을듯 합니다 **
마무리로 아이템을 화면에 표시한 후 해당 프리펩 Item에 정보를 넣어 줍니다.
** 여기에선 Instantiate로 아이템을 생성했지만 실제 게임에선 오브젝트 풀(Object Pool)을 이용해서
생성이 아닌 사용과 반납 형식으로 사용하시면 되겠네요 **
사용한 아이템을 Slot에서 삭제하는 기능은 아직 없지만 인벤토리의 작동 기능을 대충 다 만들었습니다.
여기서 아이템을 인벤토리에 넣고 테스트하는 것까지 해 보겠습니다.
버튼을 두 개 만들어 이미지의 왼쪽처럼 버튼을 인벤토리 위에 위치시켜 줍니다.
그리고 Test란 빈 오브젝트를 하나 만들고 그곳에 AddItemTest.cs를 넣어 주세요.
using UnityEngine;
public class AddItemTest : MonoBehaviour
{
[SerializeField] private Item[] items;
[SerializeField] private InventoryManager inventory;
public void AddTest(int index)
{
inventory.AddItem(items[index]);
}
}
1부 에서 만들어 두었던 bule Item과 red Item을 여기에 넣어 주세요.
InventoryManager를 넣어 주세요.
이건 위에서 만든 두 개의 Button의 Clcik 이벤트에 넣어 주시면 됩니다.
Blue Button의 index 값은 items에 blue item의 위치가 0번이니 같은 숫자로 넣어 주시고
Red Button의 index 값은 1번으로 설정하여 마무리해 주시면 됩니다.
이제 게임을 플레이하고 두 개의 Add Button을 클릭하여 아이템을 인벤토리에 넣어 보겠습니다.
4개와 5개를 생성했으면 이제 이동과 서로의 위치 교환을 해보며 또한 Slot이 아닌 다른 곳에 아이템이 위치했을 때
원래 자리로 돌아오는지 테스트해 보시기 바랍니다.
테스트결과 모든 기능이 잘 작동하고 있네요.
현재 Add 기능만 있긴 하지만 인벤토리의 기본기능은 다 구현되어 있다고 보시면 됩니다.
2부는 여기서 마무리하고 3부에선 위 이미지의 Tab 기능을 구현해 보도록 하겠습니다.
Tab을 클릭하여 A와 B Slot들을 표시하는 기능과 아이템을 드래그하여 다른 Tab위에 올려 두면
해당 Tab이 활성화되어 그곳에 아이템을 넣을 수 있는 기능까지 진행하도록 하겠습니다.
'Unity' 카테고리의 다른 글
유니티 (Unity) - 실전 인벤토리 제작 (4부) (4) | 2025.07.26 |
---|---|
유니티 (Unity) - 실전 인벤토리 제작 (3부) (0) | 2025.07.25 |
유니티 (Unity) - 실전 인벤토리 제작 (1편) (0) | 2025.07.24 |
유니티 C# - Interface 게임에 적용해 보기 (10) | 2024.07.09 |
유니티 (Unity) - 처음 만들어 보는 인벤토리 이해하기 (Inventory) (30) | 2024.07.09 |