디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

엔터티 코루틴 빌더 만들어봤는데

ㅆㅇㅆ(124.216) 2024.09.26 22:09:56
조회 44 추천 0 댓글 0



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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
 
public enum CoroutinePriority
{
    Low = 1,       // 유휴
    Medium = 2,    // 움직임
    High = 3,      // 기절
    Critical = 4   // 넉백
}
 
/// <summary>
/// 우선순위를 가진 코루틴을 관리하는 커스텀 코루틴 빌더.
/// </summary>
public class EntityCoroutineBuilder : MonoBehaviour, IEntityCoroutine
{
    /// <summary>
    /// 코루틴과 그 우선순위를 저장하는 클래스.
    /// </summary>
    private class CoroutineInfo
    {
        public CoroutinePriority Priority;
        public IEnumerator Routine;
        public bool IsActive;
 
        // For handling CustomWaitForSeconds
        public float WaitTimeRemaining;
 
        // For handling WaitForFixedUpdate
        public bool WaitForFixedUpdate;
 
        public CoroutineInfo(CoroutinePriority priority, IEnumerator routine)
        {
            Priority = priority;
            Routine = routine;
            IsActive = true;
            WaitTimeRemaining = 0f;
            WaitForFixedUpdate = false;
        }
    }
    public class CustomWaitForSeconds
    {
        public float seconds;
        public CustomWaitForSeconds(float seconds)
        {
            this.seconds = seconds;
        }
    }
 
    // 활성화된 코루틴 목록
    private List<CoroutineInfo> activeCoroutines = new List<CoroutineInfo>();
 
    /// <summary>
    /// 우선순위를 지정하여 코루틴을 시작
    /// </summary>
    /// <param name="priority">코루틴의 우선순위.</param>
    /// <param name="routine">실행할 코루틴.</param>
    public void StartCoroutineWithPriority(CoroutinePriority priority, IEnumerator routine)
    {
        if (!gameObject.activeInHierarchy)
        {
            Debug.LogWarning("코루틴을 시작할 수 없습니다. EntityCoroutineBuilder가 비활성화 상태");
            return;
        }
 
        // 더 높은 우선순위의 코루틴이 시작되면 낮은 우선순위의 코루틴을 중단
        List<CoroutinePriority> lowerPriorities = new List<CoroutinePriority>();
        foreach (var coroutine in activeCoroutines)
        {
            if (coroutine.Priority < priority && coroutine.IsActive)
            {
                lowerPriorities.Add(coroutine.Priority);
            }
        }
 
        foreach (var lowerPriority in lowerPriorities)
        {
            Debug.Log($"Stopping coroutines with priority {lowerPriority} due to new coroutine with priority {priority}.");
            StopCoroutinesByPriority(lowerPriority);
        }
 
        // 새로운 코루틴 추가
        activeCoroutines.Add(new CoroutineInfo(priority, routine));
        Debug.Log($"Starting coroutine with priority {priority}.");
    }
 
    /// <summary>
    /// 특정 우선순위의 모든 코루틴을 중지
    /// </summary>
    /// <param name="priority">중지할 코루틴의 우선순위.</param>
    public void StopCoroutinesByPriority(CoroutinePriority priority)
    {
        for (int i = activeCoroutines.Count - 1; i >= 0; i--)
        {
            var coroutine = activeCoroutines[i];
            if (coroutine.Priority == priority && coroutine.IsActive)
            {
                coroutine.IsActive = false;
                activeCoroutines.RemoveAt(i);
                Debug.Log($"Stopped coroutine with priority {priority}.");
            }
        }
    }
 
    /// <summary>
    /// 특정 우선순위의 코루틴이 실행 중인지 확인
    /// </summary>
    /// <param name="priority">확인할 우선순위.</param>
    /// <returns>해당 우선순위의 코루틴이 실행 중이면 true, 아니면 false.</returns>
    public bool IsCoroutineRunning(CoroutinePriority priority)
    {
        foreach (var coroutine in activeCoroutines)
        {
            if (coroutine.Priority == priority && coroutine.IsActive)
                return true;
        }
        return false;
    }
 
    private void Update()
    {
        // 코루틴 목록을 복사하여 수정 중 오류 방지
        var coroutinesToProcess = new List<CoroutineInfo>(activeCoroutines);
 
        foreach (var coroutine in coroutinesToProcess)
        {
            if (!coroutine.IsActive)
                continue;
 
            if (coroutine.WaitForFixedUpdate)
                continue// FixedUpdate에서 처리
 
            if (coroutine.WaitTimeRemaining > 0f)
            {
                coroutine.WaitTimeRemaining -= Time.deltaTime;
                if (coroutine.WaitTimeRemaining > 0f)
                    continue;
            }
 
            try
            {
                bool hasNext = coroutine.Routine.MoveNext();
                if (!hasNext)
                {
                    // 코루틴이 완료되었으면 목록에서 제거
                    activeCoroutines.Remove(coroutine);
                    Debug.Log($"Coroutine Priority {coroutine.Priority} completed.");
                }
                else
                {
                    HandleYieldInstruction(coroutine, coroutine.Routine.Current);
                }
            }
            catch (Exception ex)
            {
                Debug.LogError($"코루틴 실행 중 예외 발생 (우선순위 {coroutine.Priority}): {ex.Message}\n{ex.StackTrace}");
                activeCoroutines.Remove(coroutine);
            }
        }
    }
 
    private void FixedUpdate()
    {
        // 코루틴 목록을 복사하여 수정 중 오류 방지
        var coroutinesToProcess = new List<CoroutineInfo>(activeCoroutines);
 
        foreach (var coroutine in coroutinesToProcess)
        {
            if (!coroutine.IsActive)
                continue;
 
            if (!coroutine.WaitForFixedUpdate)
                continue;
 
            try
            {
                bool hasNext = coroutine.Routine.MoveNext();
                if (!hasNext)
                {
                    // 코루틴이 완료되었으면 목록에서 제거
                    activeCoroutines.Remove(coroutine);
                    Debug.Log($"Coroutine Priority {coroutine.Priority} completed.");
                }
                else
                {
                    HandleYieldInstruction(coroutine, coroutine.Routine.Current);
                }
            }
            catch (Exception ex)
            {
                Debug.LogError($"코루틴 실행 중 예외 발생 (우선순위 {coroutine.Priority}): {ex.Message}\n{ex.StackTrace}");
                activeCoroutines.Remove(coroutine);
            }
        }
    }
 
    /// <summary>
    /// YieldInstruction을 처리하는 메서드.
    /// </summary>
    /// <param name="coroutine">현재 코루틴 정보.</param>
    /// <param name="yieldObj">현재 YieldInstruction 객체.</param>
    private void HandleYieldInstruction(CoroutineInfo coroutine, object yieldObj)
    {
        if (yieldObj == null)
        {
            // 단순히 다음 프레임으로 넘어감
            return;
        }
 
        if (yieldObj is CustomWaitForSeconds customWait)
        {
            coroutine.WaitTimeRemaining = customWait.seconds;
            Debug.Log($"Coroutine Priority {coroutine.Priority}: Waiting for {customWait.seconds} seconds.");
        }
        else if (yieldObj is WaitForFixedUpdate)
        {
            coroutine.WaitForFixedUpdate = true;
            Debug.Log($"Coroutine Priority {coroutine.Priority}: Waiting for FixedUpdate.");
        }
        else
        {
            Debug.LogWarning($"지원하지 않는 YieldInstruction: {yieldObj.GetType().Name}");
        }
    }
}
 
cs


C# 내장 코루틴 이용해서 만들어볼려고 이렇게 했는데


여기서 Update랑 FixedUpate() 처리를 이벤트로해서, 기본적으로 이벤트 없을때 Upate랑 FixedUpdate() 없게 해야겠지?


기본적으로 내 아키텍쳐가 이벤트 기반이라서 코루틴 동시 다발적으로 발생할 수 있어서 스택으로 우선순위 조절해서 쓰고 있는데


Unity에서 코루틴 우선순위 관련해서 만들려고하니까 기본적으로 Update가 있어야한다네


추천 비추천

0

고정닉 0

0

댓글 영역

전체 댓글 0
등록순정렬 기준선택
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 축의금 적게 내면 눈치 줄 것 같은 스타는? 운영자 24/11/11 - -
2773232 모니터 화면에 숫자를 인식해서 알람기능을 만들수있느? 프갤러(59.2) 11.13 33 0
2773229 갓동훈 종북간첩들 잡는 검찰정상화 하겠다 [2] ♥Sub2냥덩♥갤로그로 이동합니다. 11.13 32 0
2773226 빌드에 4시간 걸리는데 회사가 컴을 안사줌 [2] ㅇㅇ(211.234) 11.13 62 0
2773224 바퀴를 다시 발명하라. [1] ㅇㅇ(118.235) 11.13 37 0
2773223 jpa 검색안하고 외워서쓰냐 [2] ㅇㅇ(61.255) 11.13 51 0
2773219 국민착취 더불어범죄당 세금만 더 높이네 ♥Sub2냥덩♥갤로그로 이동합니다. 11.13 31 0
2773215 트럼프 미합중국 대통령 ♥Sub2냥덩♥갤로그로 이동합니다. 11.13 34 0
2773214 에반게리온? 만화영화에다 의미부여하지 마라. [2] 40대프린이(118.235) 11.13 54 0
2773212 금값이 떨어져서 팔았다 살지 그냥 둘지 고민 중 발명도둑잡기갤로그로 이동합니다. 11.13 30 0
2773211 유튜브에 한남편 들면서 한녀패는 컨텐츠가 흥행하더라 헬마스터갤로그로 이동합니다. 11.13 52 1
2773210 에반게리온 일본을 침입하는 기독교 악마들 처단하는 만화 발명도둑잡기갤로그로 이동합니다. 11.13 37 0
2773209 넘나 낭만적이양✨ ㅠ ㅅ ㅠ ♥Sub2냥덩♥갤로그로 이동합니다. 11.13 38 0
2773208 스팸 [1] 발명도둑잡기갤로그로 이동합니다. 11.13 28 0
2773207 chatgpt 서버에 파일 쓰기 가능? [1] 프갤러(211.234) 11.13 51 0
2773206 오늘 헬쓰 하고 오늘 길에 외로워서 빼빼로를 샀다 발명도둑잡기갤로그로 이동합니다. 11.13 32 0
2773205 이중인격자도 아니고 무슨자격으로 나를 비판하는거지?? ㅇㅇ(223.62) 11.13 36 0
2773204 중고나라 팔릴까요? [2] 도리스아(14.35) 11.13 65 0
2773203 삼성전자가 살아날려면 그 븅신같은 걸어다니면서 폰 못쓰게 초코냥갤로그로 이동합니다. 11.13 86 0
2773202 수능 방해하면 처벌 얼마나 받냐 [1] 프갤러(118.235) 11.13 40 0
2773200 진지하게 니들이 gpt보다 나은게 머임 [2] 프갤러(106.102) 11.13 90 0
2773199 컴공와서 첫팀플인데 테스트시나리오 이거 어떻게 하는건가요 [1] ㅇㅇ갤로그로 이동합니다. 11.13 46 0
2773198 면접때 요구사항 개발프로세스 같은거 물어보냐 ㅇㅇ(118.235) 11.13 27 0
2773197 나님은 불량한 냥아치임 ㅇㅅㅇ [1] ♥Sub2냥덩♥갤로그로 이동합니다. 11.13 46 0
2773196 동덕여대 사건은 그거네- 프갤러(121.172) 11.13 54 1
2773195 북한군 아이유 사진 저는 극혐 도리스아(14.35) 11.13 40 0
2773192 오늘은 헬스장에서 YTN사이언스채널을 봤다 발명도둑잡기갤로그로 이동합니다. 11.13 39 0
2773191 범죄자 죄명아 죄를 지엇으면 벌을 달게 받거라~ ♥Sub2냥덩♥갤로그로 이동합니다. 11.13 35 0
2773190 도대체 왜 나한테 뭐라고 하는건지 이해가 안가네 ㅇㅅㅇ ㅇㅇ(223.62) 11.13 30 0
2773187 이제 삼전 떡상 할 것 같다. 매수해라. [1] 프갤러(220.86) 11.13 91 0
2773185 재용전자 오늘 또 망하셨더라 [1] 헬마스터갤로그로 이동합니다. 11.13 94 0
2773183 이번 겨울에는 뱅쇼를 도전해볼까 합니다 ㅇㅅㅇ ㅇㅇ(123.213) 11.13 32 0
2773182 예적금과 주식의 비율을 어떻게 말아야 할까 [1] 아스카영원히사랑해갤로그로 이동합니다. 11.13 45 0
2773181 기러기 인도인 일요일 그리고 어도어 프갤러(123.108) 11.13 26 0
2773179 바람의나라 클래식 게임서버 동접자 100명이 한계더라 헬마스터갤로그로 이동합니다. 11.13 48 0
2773178 Dart 말고 뭐 해야하나 프갤러(118.235) 11.13 23 0
2773176 본인 앞에서 에바 이야기 금지 [4] 아스카영원히사랑해갤로그로 이동합니다. 11.13 73 0
2773174 짐의 아내들- [6] 프갤러(121.172) 11.13 73 0
2773173 난 에바 신극도 결국 구판 재탕이라고 봄. [1] 프갤러(175.208) 11.13 25 0
2773172 참조에 참조에 더블포인터 아이 개자슥들 [2] 40대프린이(221.154) 11.13 53 0
2773170 에반게리온 하니까- 리테이크가 떠오르는군. [2] 프갤러(121.172) 11.13 51 0
2773169 내가 초딩 때는 아스카보다는 레이였는데 말이지? [2] 프갤러(121.172) 11.13 58 0
2773165 힘들구먼 [1] 아스카영원히사랑해갤로그로 이동합니다. 11.13 37 0
2773162 삼성 공채 <-- 왜 문자도 메일도 안주냐 ㅇㅇ(39.7) 11.13 88 0
2773158 어플로고제작 역할맡은 조원있는데 [3] ㅇㅇ갤로그로 이동합니다. 11.13 48 0
2773157 러스트도 아닌데 무슨 몇회를 본다느니 안부끄러움? 프갤러(121.138) 11.13 41 0
2773156 자바의 정석 몇번정도 돌림? [1] 하애갤로그로 이동합니다. 11.13 65 0
2773155 하아품- 다시 작업 시작해야지- 프갤러(121.172) 11.13 36 0
2773153 Rx 안심- 여자 이사 도웁니당- 프갤러(121.172) 11.13 30 0
2773152 api싸개가 되엇더니 내가 딸배가 된 느낌이다... 프갤러(211.234) 11.13 44 0
2773149 이사 도와줍니당- 프갤러(121.172) 11.13 51 1
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2