게임에서 상점 시스템은 플레이어들이 게임 내 아이템이나 장비를 구매하고 업그레이드하는 방법을 제공하여 게임의 새로운 경험과 도전을 제공합니다. 상점 시스템을 구현하여 플레이어가 아이템을 구매할 수 있도록 하였습니다.
💬 목차
- 총 세개의 목차로 구성되어 있습니다. 글 별로 아직 언급되지 않은 클래스의 호출이 있을 수 있습니다. 모든 글을 참조하면 충분히 이해할 수 있습니다.
1. [유니티] 상점 시스템(1) - 상점 슬롯
2. [유니티] 상점 시스템(2) - 상점
[📌현재 글] 3. [유니티] 상점 시스템(3) - 상점 매니저
📖 구현 내용
- 플레이어는 화폐를 가지고 해당 아이템을 구매할 수 있습니다.
- 에디터에서 상점에서 판매하는 아이템을 미리 등록합니다.
- 각 상점별로 상점 진척도 레벨을 이용하여 구매할 수 있는 아이템을 제한할 수 있습니다.
- 각 상점별로 판매하는 아이템은 재고가 있어 재고를 모두 소진할경우 해당 아이템을 더 이상 구매할 수 없습니다.
- 상점의 재고 및 진척도 레벨은 저장되어 나중에 게임을 로드하면 현 상태를 불러옵니다.
✅ 구현
- 이번 글의 목적은 직전 글에서 다뤘던 상점 기능을 열고 닫는 상점 매니저를 다룹니다.
- 상점 매니저는 씬 내의 모든 상점의 상점 열기 요청을 수행하여 해당 상점의 정보를 읽어 판매할 아이템들을 보여주는 역할을 수행합니다.
- UI 요소와 함께 구현합니다.
· ItemShopManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemShopManager : Singleton<ItemShopManager>
{
private static bool mIsItemShopActive = false;
public static bool IsItemShopActive
{
get
{
return mIsItemShopActive;
}
}
[Header("상점 오브젝트 루트 오브젝트")]
[SerializeField] public GameObject mShopRootGo;
[Header("상점 오브젝트의 프리팹 인스턴스 트랜스폼")]
[SerializeField] public Transform mSlotInstantiateTransform;
[Header("상점 슬롯 프리팹")]
[SerializeField] public GameObject mShopSlotPrefab;
private List<ItemShopSlot> mCurrentSlots = new List<ItemShopSlot>(); // 현재 인스턴스된 슬롯들
private void Awake()
{
// 초기화시 전역 활성화상태 해제
ItemShopManager.mIsItemShopActive = false;
}
/// <summary>
/// 상점으로부터 호출되어 아이템 상점 다이얼로그를 열음
/// </summary>
/// <param name="sellItems">상점에서 판매하는 아이템들</param>
/// <param name="shopLevel">상점의 진척도 레벨</param>
public void OpenItemShop(ItemShopSlotInfo[] sellItems, int shopLevel)
{
foreach(ItemShopSlotInfo sellItem in sellItems)
{
ItemShopSlot slot = Instantiate(mShopSlotPrefab, Vector3.zero, Quaternion.identity, mSlotInstantiateTransform).GetComponent<ItemShopSlot>();
slot.InitSlot(sellItem, shopLevel);
mCurrentSlots.Add(slot);
}
mShopRootGo.SetActive(true);
// 모든 슬롯을 갱신
ItemShopManager.Instance.RefreshSlots();
// 활성화 토글
mIsItemShopActive = true;
UtilityManager.UnlockCursor();
}
/// <summary>
/// 상점 다이얼로그를 닫음
/// </summary>
public void CloseItemShop()
{
foreach(ItemShopSlot slot in mCurrentSlots)
Destroy(slot.gameObject);
mCurrentSlots.Clear();
mShopRootGo.SetActive(false);
// 비활성화 토글
mIsItemShopActive = false;
UtilityManager.TryLockCursor();
}
/// <summary>
/// 상점 다이얼로그를 갱신
/// </summary>
public void RefreshSlots()
{
// 각 슬롯 갱신 호출
foreach(ItemShopSlot slot in mCurrentSlots)
slot.RefreshSlot();
// 라벨 갱신
InventoryMain.Instance.RefreshLabels();
}
}
private static bool mIsItemShopActive = false;
public static bool IsItemShopActive
{
get
{
return mIsItemShopActive;
}
}
- 현재 상점 다이얼로그창이 활성화 되어있는지 확인하기위한 변수입니다.
[Header("상점 오브젝트 루트 오브젝트")]
[SerializeField] public GameObject mShopRootGo;
- 다이얼로그 창을 열고 닫기 위한 UI요소 루트 게임오브젝트입니다.
[Header("상점 오브젝트의 프리팹 인스턴스 트랜스폼")]
[SerializeField] public Transform mSlotInstantiateTransform;
- 상점에서 판매하는 아이템을 슬롯으로 보여주기 위해 슬롯을 인스턴스할때 위치시킬 부모 트랜스폼입니다.
[Header("상점 슬롯 프리팹")]
[SerializeField] public GameObject mShopSlotPrefab;
- 상점에서 판매하는 아이템을 슬롯으로 보여주기위해 인스턴스를 할 프리팹입니다.
/// <summary>
/// 상점으로부터 호출되어 아이템 상점 다이얼로그를 열음
/// </summary>
/// <param name="sellItems">상점에서 판매하는 아이템들</param>
/// <param name="shopLevel">상점의 진척도 레벨</param>
public void OpenItemShop(ItemShopSlotInfo[] sellItems, int shopLevel)
{
foreach(ItemShopSlotInfo sellItem in sellItems)
{
ItemShopSlot slot = Instantiate(mShopSlotPrefab, Vector3.zero, Quaternion.identity, mSlotInstantiateTransform).GetComponent<ItemShopSlot>();
slot.InitSlot(sellItem, shopLevel);
mCurrentSlots.Add(slot);
}
mShopRootGo.SetActive(true);
// 모든 슬롯을 갱신
ItemShopManager.Instance.RefreshSlots();
// 활성화 토글
mIsItemShopActive = true;
UtilityManager.UnlockCursor();
}
- ItemShop.cs로부터 호출되어 상점 매니저인 이 클래스에게 상점 다이얼로그를 열도록 요청합니다.
- sellItems를 이용하여 판매할 아이템들을 가지고오고 슬롯을 생성하여 해당 슬롯을 초기화합니다.
/// <summary>
/// 상점 다이얼로그를 닫음
/// </summary>
public void CloseItemShop()
{
foreach(ItemShopSlot slot in mCurrentSlots)
Destroy(slot.gameObject);
mCurrentSlots.Clear();
mShopRootGo.SetActive(false);
// 비활성화 토글
mIsItemShopActive = false;
UtilityManager.TryLockCursor();
}
- 상점 다이얼로그를 닫습니다.
/// <summary>
/// 상점 다이얼로그를 갱신
/// </summary>
public void RefreshSlots()
{
// 각 슬롯 갱신 호출
foreach(ItemShopSlot slot in mCurrentSlots)
slot.RefreshSlot();
// 라벨 갱신
InventoryMain.Instance.RefreshLabels();
}
- 필요한경우 상점 내부의 슬롯을 갱신합니다.
- 예를 들어 아이템을 구매하여 아이템 재고 등을 갱신하기위해 사용할 수 있습니다.
· UI
- 스크롤 뷰를 이용하여 판매할 아이템을 보여줄 수 있도록 합니다.
- 사용할 UI와 매니저입니다.
- 매니저는 싱글턴으로 구현하여 런타임 도중 비활성화되지 않도록 합니다.
- M Shop Slot Prefab은 첫번째 글에서 구현하는 프리팹입니다.
📺 결과
'unity game modules' 카테고리의 다른 글
[유니티] 제작 시스템(2) - 제작 슬롯 (0) | 2023.04.02 |
---|---|
[유니티] 제작 시스템(1) - 레시피 (0) | 2023.04.02 |
[유니티] 상점 시스템(2) - 상점 (0) | 2023.04.02 |
[유니티] 상점 시스템(1) - 상점 슬롯 (0) | 2023.04.02 |
[유니티] 경사면 미끄러짐 (0) | 2023.03.27 |