SkillManager.cs
- 스킬 관리 시스템
- 스킬 요청, 종료, 스킬 대기열, 오브젝트 풀링 등 처리
public class SkillManager : MonoBehaviour
{
[Header("SO")]
[SerializeField] private SkillEventChannelSO skillEventChannel;
[SerializeField] private PlayerEquipSkillSO equipSkillSO;
[Header("Folder")]
[SerializeField] private Transform skillFolder;
[Header("Pool")]
[SerializeField] private SkillPool skillPool;
private SkillQueue skillQueue = new();
private bool isSkillSpawnable = false;
private float spawnTimer = 0;
private const float skillTerm = 1f;
private void OnEnable()
{
skillEventChannel.OnFinishSkillEvent += SkillRelease;
}
private void OnDisable()
{
skillEventChannel.OnFinishSkillEvent -= SkillRelease;
}
private void Start() => Setup();
private void Setup()
{
for (int i = 0; i < equipSkillSO.GetEquipCount(); i++)
{
SkillBookSO skill = equipSkillSO.equipSkill[i];
skillPool.InitPool(skill.skillName, skill.skillPrefab);
}
}
// 스킬 스폰 요청
private void SkillSpawn(SkillBookSO skillBook, Vector3 skillPosition)
{
SkillController skill = skillPool.Get(skillBook.skillName);
skill.Setup(skillBook);
skill.transform.SetParent(skillFolder);
skill.transform.position = skillPosition;
// 스킬 큐가 비어있다면
if (skillQueue.IsEmptyQueue() && isSkillSpawnable == true)
{
InitSpawnTimer();
skill.Play();
}
else
skillQueue.Push(skill);
}
// 스킬 릴리스
private void SkillRelease(SkillBookSO skillBook, SkillController skill) => skillPool.Release(skillBook.skillName, skill);
private void ExecuteSkillQueue()
{
// 스킬 큐가 존재한다면
if (!skillQueue.IsEmptyQueue())
{
InitSpawnTimer();
SkillController nextSkill = skillQueue.Pop();
nextSkill.Play();
}
}
// Auto
private void InitSpawnTimer() => spawnTimer = 0;
private void Update()
{
spawnTimer += Time.deltaTime;
isSkillSpawnable = spawnTimer >= skillTerm ? true : false;
if (isSkillSpawnable)
ExecuteSkillQueue();
}
}
SkillEventChannelSO.cs
[CreateAssetMenu(menuName = "MySO/EventChannel/SkillEventChannerlSO", fileName = "SkillEventChannerlSO")]
public class SkillEventChannelSO : ScriptableObject
{
public Action<SkillBookSO> OnSpawnSkillEvent;
public Action<SkillBookSO, SkillController> OnFinishSkillEvent;
public void SpawnSkill(SkillBookSO skillBook) => OnSpawnSkillEvent?.Invoke(skillBook);
public void FinishSkill(SkillBookSO skillBook, SkillController skill) => OnFinishSkillEvent?.Invoke(skillBook, skill);
}
PlayerEquipSkillSO.cs
- 현재 플레이어의 스킬 장착 정보
- 에디터에서 조작 가능
[CreateAssetMenu(menuName = "MySO/Data/Player/PlayerEquipSkillSO", fileName = "PlayerEquipSkillSO")]
public class PlayerEquipSkillSO : ScriptableObject
{
[field: SerializeField] public List<SkillBookSO> equipSkill = new();
public int GetEquipCount() => equipSkill.Count;
// 액티브만 추가 가능하도록 체크가 필요
}
SkillBookSO.cs
[CreateAssetMenu(menuName = "MySO/Data/Book/SkillBook", fileName = "SkillBook")]
public class SkillBookSO : ScriptableObject, ILevelUpValue<float>, IPercentValue<float>
{
[field: SerializeField] public int index { get; set; }
[field: SerializeField] public string code { get; set; }
[field: SerializeField] public string skillName { get; set; }
[field: SerializeField] public ESkillTree skillTree { get; set; }
[field: SerializeField] public ESkillType skillType { get; set; }
[field: SerializeField] public int grade { get; set; } // 차수
[field: SerializeField] public string explain { get; set; }
[field: SerializeField] public int entityCount { get; set; }
[field: SerializeField] public int hitCount { get; set; }
[field: SerializeField] public float duration { get; set; }
[field: SerializeField] public float coolTime { get; set; }
[field: SerializeField] public int needPoint { get; set; }
[field: SerializeField] public bool multiAttack { get; set; }
[field: SerializeField] public float start { get; set; }
[field: SerializeField] public float raise { get; set; }
[field: SerializeField] public int maxLevel { get; set; }
[field: SerializeField] public GameObject skillPrefab { get; set; }
public float GetValue(int levelIndex)
{
levelIndex = levelIndex > maxLevel ? maxLevel : levelIndex;
return start + raise * levelIndex;
}
public string GetPercent(int level) => $"{GetValue(level) * 100f}%";
}
SkillQueue.cs