✅ 기능
게임에서 아이템 및 스킬 등 플레이어가 사용하는 기능이 있는 시스템에서 쿨타임은 매우 중요한 요소입니다. 쿨타임을 활용하여 게임의 밸런스를 조정하고, 플레이어의 역량을 제한할 수 있는 등 중요한 기능을 수행할 수 있습니다. 매우 간단한 방법으로 구현한 쿨타임 기능을 적용하여 정리하였습니다. 이 글에서 다루는 기능은 [인벤토리 시스템]을 기반으로 만들어져 있습니다.
✅ 흐름도
✅ 사용 예시
✅ 구현
1. ItemCooltimeManager
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemCooltimeManager : Singleton<ItemCooltimeManager>
{
private Dictionary<int, float> mCooltimes; //돌고있는 쿨타임들을 가지고있는 딕셔너리
private List<int> mCooltimeList; //현재 돌고있는 쿨타임들의 아이템 코드를 담는 리스트
private float mTempCooltime; //임시 저장용 변수
private void Start()
{
mCooltimes = new Dictionary<int, float>();
mCooltimeList = new List<int>();
}
private void Update()
{
//현재 리스트에 들어있는 모든 요소들을 돌면서 쿨타임을 확인
for (int i = mCooltimeList.Count - 1; i >= 0; --i)
{
//매 프레임마다 쿨타임 갱신
mTempCooltime = mCooltimes[mCooltimeList[i]] = mCooltimes[mCooltimeList[i]] - Time.deltaTime;
//쿨타임이 끝났다면 리스트에서 요소 제거
if(mTempCooltime < 0) { mCooltimeList.RemoveAt(i); }
}
}
/// <summary>
/// 쿨타임 대기열에 아이템코드가 itemID인 대상의 쿨타임을 시작한다
/// </summary>
/// <param name="itemID">아이템 코드</param>
/// <param name="originCooltime">해당 아이템의 오리진 쿨타임</param>
public void AddCooltimeQueue(int itemID, float originCooltime)
{
mCooltimes.TryAdd(itemID, originCooltime);
mCooltimes[itemID] = originCooltime;
mCooltimeList.Add(itemID);
}
/// <summary>
/// 해당 아이템의 남은 쿨타임 시간을 가져온다
/// </summary>
/// <param name="itemID">확인할 쿨타임의 아이템</param>
/// <returns></returns>
public float GetCurrentCooltime(int itemID)
{
float cooltime;
bool isSuccess = mCooltimes.TryGetValue(itemID, out cooltime);
if (isSuccess) { return cooltime; }
else { return 0; }
}
}
- 아이템 쿨타임 기능을 담당할 쿨타임 매니저입니다.
- 매니저와 같이 씬 내에 하나만 존재해야 하며, 매 프레임마다 Update()에서 쿨타임이 돌고 있는 아이템에 대한 쿨타임시간을 계산하도록 설계하였습니다.
private Dictionary<int, float> mCooltimes; //돌고있는 쿨타임들을 가지고있는 딕셔너리
- 외부에서 아이템의 itemID를 기반으로 남은 쿨타임을 획득하기위해 사용하는 딕셔너리입니다.
- 조회를 할 때 시간복잡도BigO(1)인 상수시간을 가지는 점을 고려하여 딕셔너리로 구현하였습니다.
private List<int> mCooltimeList; //현재 돌고있는 쿨타임들의 아이템 코드를 담는 리스트
- 현재 쿨타임이 돌고있는(현재 쿨타임인) 아이템들의 itemID를 저장하는 리스트입니다.
- 프레임마다 Update()에서 리스트의 모든 요소를 순회하여 딕셔너리에 있는 남은 쿨타임 시간을 갱신하기 위해 사용합니다.
private void Update()
- mCooltimeList의 모든 요소를 한 번씩 순회하여 리스트의 요소인 itemID를 key로 하는 딕셔너리의 요소에 접근하여 쿨타임 시간을 갱신합니다.
- 만약 어떠한 key를 가진 쿨타임시간이 0보다 작다면, 쿨타임이 끝난 것으로 판단하여 리스트에서 제거하도록 하였습니다.
- 이미 쿨타임이 끝났기때문에 Update()에서 불필요한 요소 순회를 할 필요가 없기에 제거합니다.
public void AddCooltimeQueue(int itemID, float originCooltime)
- 아이템을 성공적으로 사용했을경우, 해당 itemID에 대해 쿨타임을 적용합니다.
- 만약 딕셔너리에 itemID로 되어있는 key 요소가 없는 경우, 생성합니다.
- 순회를 하기 위해 mCooltimeList에 itemID를 삽입합니다.
public float GetCurrentCooltime(int itemID)
- itemID에 대한 아이템의 쿨타임을 획득합니다.
2. InventorySlot
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// 인벤토리 슬롯 하나를 담당
/// </summary>
public class InventorySlot : MonoBehaviour, IPointerClickHandler, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler, IPointerEnterHandler, IPointerExitHandler
{
...
[SerializeField] private Image mCooltimeImage; //아이템 쿨타임 이미지
...
private void Update()
{
//아이템 쿨타임 스프라이트를 쿨타임 기반으로 계산하여 채운다.
if (mItem != null) { mCooltimeImage.fillAmount = ItemCooltimeManager.Instance.GetCurrentCooltime(mItem.ItemID) / mItem.Cooltime; }
else { mCooltimeImage.fillAmount = 0.0f; }
}
...
}
- InventorySlot에서 쿨타임을 시각적으로 보여주기 위해 쿨타임 이미지를 만들고, 매 프레임마다 fillAmount를 이용하여 채우는 양을 조절합니다.
- 인벤토리 내의 모든 아이템에 대해 쿨타임을 동기화하여 동일하게 쿨타임을 적용할 수 있습니다.
'unity game modules' 카테고리의 다른 글
[유니티] 레터박스(Lettering Box) 구현하기 (0) | 2023.01.06 |
---|---|
[유니티] VideoPlayer URL 재생 및 관리 (0) | 2023.01.02 |
[유니티] 인벤토리 시스템(6) - 아이템 사용 (0) | 2022.12.27 |
[유니티] 인벤토리 시스템(5) - 아이템 슬롯 관리 (0) | 2022.12.26 |
[유니티] 인벤토리 시스템(4) - 아이템 획득 (0) | 2022.12.26 |