Skip to content

Commit ace4ee7

Browse files
committed
feat: 스켈레톤 코드 작성
1 parent 18249f1 commit ace4ee7

16 files changed

+884
-0
lines changed
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
using System;
2+
3+
namespace ProjectVG.Domain.Character.Service
4+
{
5+
/// <summary>
6+
/// 캐릭터 액션 요청을 나타내는 DTO
7+
/// </summary>
8+
[Serializable]
9+
public struct CharacterActionRequest
10+
{
11+
/// <summary>
12+
/// 대상 캐릭터 ID
13+
/// </summary>
14+
public string CharacterId;
15+
16+
/// <summary>
17+
/// 액션 키 (예: "happy", "wave", "nod")
18+
/// </summary>
19+
public string ActionKey;
20+
21+
/// <summary>
22+
/// 액션 강도 (0.0 ~ 1.0)
23+
/// </summary>
24+
public float Intensity;
25+
26+
/// <summary>
27+
/// 액션 지속 시간 (밀리초, null이면 기본값 사용)
28+
/// </summary>
29+
public int? DurationMs;
30+
31+
/// <summary>
32+
/// 액션 우선순위
33+
/// </summary>
34+
public CharacterActionPriority Priority;
35+
36+
/// <summary>
37+
/// 액션 취소 정책
38+
/// </summary>
39+
public CharacterCancelPolicy CancelPolicy;
40+
41+
public CharacterActionRequest(string characterId, string actionKey, float intensity = 1.0f, int? durationMs = null, CharacterActionPriority priority = CharacterActionPriority.Normal, CharacterCancelPolicy cancelPolicy = CharacterCancelPolicy.Replace)
42+
{
43+
CharacterId = characterId;
44+
ActionKey = actionKey;
45+
Intensity = intensity;
46+
DurationMs = durationMs;
47+
Priority = priority;
48+
CancelPolicy = cancelPolicy;
49+
}
50+
}
51+
52+
/// <summary>
53+
/// 캐릭터 액션 핸들 (액션 실행 추적용)
54+
/// </summary>
55+
[Serializable]
56+
public struct CharacterActionHandle
57+
{
58+
/// <summary>
59+
/// 액션 고유 ID
60+
/// </summary>
61+
public string ActionId;
62+
63+
/// <summary>
64+
/// 액션 상태
65+
/// </summary>
66+
public CharacterActionStatus Status;
67+
68+
public CharacterActionHandle(string actionId, CharacterActionStatus status = CharacterActionStatus.Pending)
69+
{
70+
ActionId = actionId;
71+
Status = status;
72+
}
73+
}
74+
75+
/// <summary>
76+
/// 캐릭터 액션 상태 정보
77+
/// </summary>
78+
[Serializable]
79+
public struct CharacterActionState
80+
{
81+
/// <summary>
82+
/// 현재 실행 중인 액션 ID
83+
/// </summary>
84+
public string CurrentActionId;
85+
86+
/// <summary>
87+
/// 현재 실행 중인 액션 키
88+
/// </summary>
89+
public string CurrentActionKey;
90+
91+
/// <summary>
92+
/// 액션이 재생 중인지 여부
93+
/// </summary>
94+
public bool IsPlaying;
95+
96+
/// <summary>
97+
/// 음성 게이트가 활성화되어 있는지 여부
98+
/// </summary>
99+
public bool IsVoiceGated;
100+
101+
public CharacterActionState(string currentActionId = null, string currentActionKey = null, bool isPlaying = false, bool isVoiceGated = false)
102+
{
103+
CurrentActionId = currentActionId;
104+
CurrentActionKey = currentActionKey;
105+
IsPlaying = isPlaying;
106+
IsVoiceGated = isVoiceGated;
107+
}
108+
}
109+
110+
/// <summary>
111+
/// 해석된 캐릭터 액션 정보
112+
/// </summary>
113+
[Serializable]
114+
public struct CharacterResolvedAction
115+
{
116+
/// <summary>
117+
/// 표현식 키
118+
/// </summary>
119+
public string ExpressionKey;
120+
121+
/// <summary>
122+
/// 모션 키
123+
/// </summary>
124+
public string MotionKey;
125+
126+
/// <summary>
127+
/// 지속 시간 (밀리초)
128+
/// </summary>
129+
public int? DurationMs;
130+
131+
/// <summary>
132+
/// 블렌드 인 시간 (초)
133+
/// </summary>
134+
public float BlendInSec;
135+
136+
/// <summary>
137+
/// 블렌드 아웃 시간 (초)
138+
/// </summary>
139+
public float BlendOutSec;
140+
141+
public CharacterResolvedAction(string expressionKey = null, string motionKey = null, int? durationMs = null, float blendInSec = 0.3f, float blendOutSec = 0.3f)
142+
{
143+
ExpressionKey = expressionKey;
144+
MotionKey = motionKey;
145+
DurationMs = durationMs;
146+
BlendInSec = blendInSec;
147+
BlendOutSec = blendOutSec;
148+
}
149+
}
150+
151+
/// <summary>
152+
/// 캐릭터 액션 우선순위
153+
/// </summary>
154+
public enum CharacterActionPriority
155+
{
156+
/// <summary>
157+
/// 낮은 우선순위
158+
/// </summary>
159+
Low = 0,
160+
161+
/// <summary>
162+
/// 일반 우선순위
163+
/// </summary>
164+
Normal = 1,
165+
166+
/// <summary>
167+
/// 높은 우선순위
168+
/// </summary>
169+
High = 2,
170+
171+
/// <summary>
172+
/// 최고 우선순위 (음성 등)
173+
/// </summary>
174+
Critical = 3
175+
}
176+
177+
/// <summary>
178+
/// 캐릭터 액션 취소 정책
179+
/// </summary>
180+
public enum CharacterCancelPolicy
181+
{
182+
/// <summary>
183+
/// 기존 액션을 대체
184+
/// </summary>
185+
Replace = 0,
186+
187+
/// <summary>
188+
/// 기존 액션이 완료될 때까지 대기
189+
/// </summary>
190+
Wait = 1,
191+
192+
/// <summary>
193+
/// 기존 액션을 중단하고 즉시 실행
194+
/// </summary>
195+
Interrupt = 2,
196+
197+
/// <summary>
198+
/// 기존 액션이 우선순위가 낮을 때만 대체
199+
/// </summary>
200+
ReplaceIfLowerPriority = 3
201+
}
202+
203+
/// <summary>
204+
/// 캐릭터 액션 상태
205+
/// </summary>
206+
public enum CharacterActionStatus
207+
{
208+
/// <summary>
209+
/// 대기 중
210+
/// </summary>
211+
Pending = 0,
212+
213+
/// <summary>
214+
/// 실행 중
215+
/// </summary>
216+
Playing = 1,
217+
218+
/// <summary>
219+
/// 완료됨
220+
/// </summary>
221+
Completed = 2,
222+
223+
/// <summary>
224+
/// 취소됨
225+
/// </summary>
226+
Cancelled = 3,
227+
228+
/// <summary>
229+
/// 오류 발생
230+
/// </summary>
231+
Error = 4
232+
}
233+
}

Assets/Domain/Character/Script/Controller/CharacterActionDTOs.cs.meta

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Domain/Character/Script/Facade.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
using UnityEngine;
2+
using ProjectVG.Domain.Character.Live2D.Model;
3+
4+
namespace ProjectVG.Domain.Character.Service
5+
{
6+
/// <summary>
7+
/// 캐릭터 제어를 단일 진입점으로 제공하는 파사드 구현체.
8+
/// </summary>
9+
public class CharacterFacade : MonoBehaviour, ICharacterFacade
10+
{
11+
private ICharacterModelManager _modelManager;
12+
private ICharacterActionService _actionService;
13+
private ICharacterActionResolver _actionResolver;
14+
15+
/// <summary>
16+
/// 파사드를 초기화한다.
17+
/// </summary>
18+
public void Initialize()
19+
{
20+
// 의존성 주입을 통해 초기화
21+
// TODO: 실제 의존성 주입 컨테이너에서 가져오도록 수정
22+
Debug.LogWarning("[CharacterFacade] 의존성 주입이 아직 구현되지 않았습니다.");
23+
}
24+
25+
/// <summary>
26+
/// 의존성을 주입한다.
27+
/// </summary>
28+
/// <param name="modelManager">모델 매니저</param>
29+
/// <param name="actionService">액션 서비스</param>
30+
/// <param name="actionResolver">액션 해석기</param>
31+
public void InjectDependencies(ICharacterModelManager modelManager, ICharacterActionService actionService, ICharacterActionResolver actionResolver)
32+
{
33+
_modelManager = modelManager;
34+
_actionService = actionService;
35+
_actionResolver = actionResolver;
36+
}
37+
38+
/// <summary>
39+
/// 파사드를 종료한다.
40+
/// </summary>
41+
public void Shutdown()
42+
{
43+
if (_modelManager != null) {
44+
_modelManager.UnloadAll();
45+
}
46+
}
47+
48+
/// <summary>
49+
/// 캐릭터를 등록한다.
50+
/// </summary>
51+
public void RegisterCharacter(string characterId, bool preload = false)
52+
{
53+
if (_modelManager != null) {
54+
_modelManager.LoadModel(characterId, preload);
55+
}
56+
}
57+
58+
/// <summary>
59+
/// 캐릭터 등록을 해제한다.
60+
/// </summary>
61+
public void UnregisterCharacter(string characterId)
62+
{
63+
if (_modelManager != null) {
64+
_modelManager.UnloadModel(characterId);
65+
}
66+
}
67+
68+
/// <summary>
69+
/// 활성 캐릭터를 설정한다.
70+
/// </summary>
71+
public void SetActiveCharacter(string characterId)
72+
{
73+
if (_modelManager != null) {
74+
_modelManager.ActivateModel(characterId);
75+
}
76+
}
77+
78+
/// <summary>
79+
/// 활성 캐릭터를 해제한다.
80+
/// </summary>
81+
public void ClearActiveCharacter()
82+
{
83+
if (_modelManager != null) {
84+
_modelManager.DeactivateModel();
85+
}
86+
}
87+
88+
/// <summary>
89+
/// 액션을 적용한다.
90+
/// </summary>
91+
public CharacterActionHandle ApplyAction(CharacterActionRequest request)
92+
{
93+
// TODO: 액션 서비스 구현 후 연결
94+
Debug.LogWarning($"[CharacterFacade] ApplyAction 아직 구현되지 않음: {request.ActionKey}");
95+
return new CharacterActionHandle("not_implemented", CharacterActionStatus.Error);
96+
}
97+
98+
/// <summary>
99+
/// 액션을 취소한다.
100+
/// </summary>
101+
public void CancelAction(string actionId)
102+
{
103+
// TODO: 액션 서비스 구현 후 연결
104+
Debug.LogWarning($"[CharacterFacade] CancelAction 아직 구현되지 않음: {actionId}");
105+
}
106+
107+
/// <summary>
108+
/// 모든 액션을 취소한다.
109+
/// </summary>
110+
public void CancelAllActions()
111+
{
112+
// TODO: 액션 서비스 구현 후 연결
113+
Debug.LogWarning("[CharacterFacade] CancelAllActions 아직 구현되지 않음");
114+
}
115+
116+
/// <summary>
117+
/// 음성 재생 시작을 알린다.
118+
/// </summary>
119+
public void OnVoiceStarted()
120+
{
121+
// TODO: 음성 관련 처리 구현
122+
}
123+
124+
/// <summary>
125+
/// 음성 재생 종료를 알린다.
126+
/// </summary>
127+
public void OnVoiceFinished()
128+
{
129+
// TODO: 음성 관련 처리 구현
130+
}
131+
132+
/// <summary>
133+
/// 활성 캐릭터 ID를 반환한다.
134+
/// </summary>
135+
public string GetActiveCharacterId()
136+
{
137+
return _modelManager?.GetActiveModelId();
138+
}
139+
140+
/// <summary>
141+
/// 캐릭터 등록 여부를 반환한다.
142+
/// </summary>
143+
public bool IsRegistered(string characterId)
144+
{
145+
return _modelManager?.IsLoaded(characterId) ?? false;
146+
}
147+
}
148+
}
149+

0 commit comments

Comments
 (0)