스탯 시스템을 구현해본다.
이 스탯 시스템을 바탕으로 아이템도 구현해본다.
using System.Collections.Generic;
using UnityEngine;
public enum StatType
{
Health,
Speed,
ProjectileCount,
}
[CreateAssetMenu(fileName = "New StatData", menuName = "Stats/Chracter Stats")]
public class StatData : ScriptableObject
{
public string characterName;
public List<StatEntry> stats;
}
[System.Serializable]
public class StatEntry
{
public StatType statType;
public float baseValue;
}
위의 스탯 데이터 클래스는 스크립터블 오브젝트로
스탯에 대한 정보를 StatEntry
객체로 저장한다.
StatEntry
는 순수 데이터 코드로 Serializable
이라 StatData
의 목록으로 직렬화하며,
위의 열겨형(StatType
) 과 열거형 타입의 값을 가진다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StatHandler : MonoBehaviour
{
public StatData statData;
private Dictionary<StatType, float> currentStats = new Dictionary<StatType, float>();
private void Awake()
{
InitializeStats();
}
private void InitializeStats()
{
foreach (StatEntry entry in statData.stats)
{
currentStats[entry.statType] = entry.baseValue;
}
}
public float GetStat(StatType statType)
{
return currentStats.ContainsKey(statType) ? currentStats[statType] : 0;
}
public void ModifyStat(StatType statType, float amount, bool isPermanent = true, float duration = 0)
{
if (!currentStats.ContainsKey(statType)) return;
currentStats[statType] += amount;
if (!isPermanent)
{
StartCoroutine(RemoveStatAfterDuration(statType, amount, duration));
}
}
private IEnumerator RemoveStatAfterDuration(StatType statType, float amount, float duration)
{
yield return new WaitForSeconds(duration);
currentStats[statType] -= amount;
}
}
위 스크립트는 스탯을 다루는 기능을 가진 클래스로,
필드에 선언한 statData
와 currentStats
를
InitializeStats()
에서 딕셔너리인 currentStats
에
statData
에 들어가있는 StatEntry
리스트를
키를 StatType로, baseValue를 값으로 저장한다.
public float GetStat(StatType statType)
은
외부에서 현재 스탯 값을 안전하게 조회하도록 제공하는 읽기 전용 API로
조회할 스탯 종류를 매개변수로 받아서 키에 대응하는 값을 반환한다.