근데 그럼 싱글톤인데, 싱글톤 관리가 나을까

아니면 방금 만들어서 컴포넌트 엔터티 단위로 부착시켜서 관리할까


싱글톤은 만들기 편하긴한데 손댈때마다, 나중에 테스트가 버거워져서 만들기 꺼려짐


그리고 Task면 다른쓰레드서 접근 못하게 락 걸어야하는데, 생각보다 이것도 까다롭고


짜증




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public enum CoroutinePriority
{
    Low = 1,//Idle
    Medium = 2,//움직임
    High = 3,//상태이상
    Critical = 4//넉백
}
 
public class EntityCoroutineBuilder : MonoBehaviour
{
    // 각 우선순위별로 여러 코루틴을 관리하기 위해 List<Coroutine> 사용
    private Dictionary<CoroutinePriority, List<Coroutine>> activeCoroutines = new Dictionary<CoroutinePriority, List<Coroutine>>();
 
    /// <summary>
    /// 코루틴을 시작. 우선순위에 따라 기존 코루틴을 중지할지 결정
    /// </summary>
    /// <param name="priority">코루틴의 우선순위</param>
    /// <param name="routine">실행할 코루틴</param>
    public void StartCoroutineWithPriority(CoroutinePriority priority, IEnumerator routine)
    {
        // 우선순위에 따라 기존 코루틴 중지
        List<CoroutinePriority> existingPriorities = new List<CoroutinePriority>(activeCoroutines.Keys);
        foreach (CoroutinePriority existingPriority in existingPriorities)
        {
            if (existingPriority >= priority)
            {
                if (activeCoroutines.TryGetValue(existingPriority, out List<Coroutine> coroutines))
                {
                    foreach (Coroutine coroutine in coroutines)
                    {
                        StopCoroutine(coroutine);
                    }
                    activeCoroutines.Remove(existingPriority);
                }
            }
        }
 
        // 새로운 코루틴 시작
        Coroutine coroutineInstance = StartCoroutine(RoutineWrapper(priority, routine));
 
        // 코루틴을 우선순위에 맞게 리스트에 추가
        if (!activeCoroutines.ContainsKey(priority))
        {
            activeCoroutines[priority] = new List<Coroutine>();
        }
        activeCoroutines[priority].Add(coroutineInstance);
    }
 
    /// <summary>
    /// 코루틴을 중지
    /// </summary>
    /// <param name="priority">코루틴의 우선순위</param>
    public void StopCoroutineByPriority(CoroutinePriority priority)
    {
        if (activeCoroutines.ContainsKey(priority))
        {
            foreach (Coroutine coroutine in activeCoroutines[priority])
            {
                StopCoroutine(coroutine);
            }
            activeCoroutines.Remove(priority);
        }
    }
 
    /// <summary>
    /// 코루틴의 실행을 래핑하여 종료 시 우선순위를 초기화
    /// </summary>
    /// <param name="priority">코루틴의 우선순위</param>
    /// <param name="routine">실행할 코루틴</param>
    /// <returns>IEnumerator</returns>
    private IEnumerator RoutineWrapper(CoroutinePriority priority, IEnumerator routine)
    {
        yield return StartCoroutine(routine);
        if (activeCoroutines.ContainsKey(priority))
        {
            activeCoroutines[priority].RemoveAll(c => c == null);
            if (activeCoroutines[priority].Count == 0)
            {
                activeCoroutines.Remove(priority);
            }
        }
    }
 
    /// <summary>
    /// 특정 우선순위의 코루틴이 실행 중인지 확인
    /// </summary>
    /// <param name="priority">코루틴의 우선순위</param>
    /// <returns>실행 중이면 true, 아니면 false</returns>
    public bool IsCoroutineRunning(CoroutinePriority priority)
    {
        return activeCoroutines.ContainsKey(priority) && activeCoroutines[priority].Count > 0;
    }
}
 
cs