Skip to content

Commit 18249f1

Browse files
committed
feat: livw2d 기능 스켈레톤 코드 작성
1 parent 4a15565 commit 18249f1

13 files changed

+834
-115
lines changed
Lines changed: 185 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,192 @@
11
using UnityEngine;
2+
using System;
3+
using System.Collections;
4+
using Live2D.Cubism.Framework.Motion;
25

36
namespace ProjectVG.Domain.Character.Service
47
{
5-
/// <summary>
6-
/// 행동 → 모션/파라미터 트리거를 구현하는 컨트롤러의 스켈레톤.
7-
/// </summary>
8-
public class ActionController : MonoBehaviour, IActionController
9-
{
10-
public void Initialize()
11-
{
12-
}
13-
14-
public void TriggerAction(string action, object args = null)
15-
{
16-
}
17-
}
8+
/// <summary>
9+
/// 행동 → 모션/파라미터 트리거를 구현하는 컨트롤러
10+
/// </summary>
11+
public class ActionController : MonoBehaviour, IActionController
12+
{
13+
[Header("Components")]
14+
[SerializeField] private CubismMotionController _motionController;
15+
16+
[Header("Action Mapping")]
17+
[SerializeField] private ActionMotionMapping[] _actionMappings;
18+
19+
[Header("Settings")]
20+
[SerializeField] private float _defaultMotionDuration = 2.0f;
21+
22+
private string _currentAction;
23+
private Coroutine _actionCoroutine;
24+
private bool _isActionPlaying = false;
25+
26+
#region IActionController Implementation
27+
28+
public void Initialize()
29+
{
30+
if (_motionController == null)
31+
{
32+
_motionController = GetComponent<CubismMotionController>();
33+
}
34+
35+
if (_motionController == null)
36+
{
37+
Debug.LogError("[ActionController] CubismMotionController를 찾을 수 없습니다.");
38+
return;
39+
}
40+
41+
Debug.Log("[ActionController] 초기화 완료");
42+
}
43+
44+
public void TriggerAction(string action, object args = null)
45+
{
46+
if (string.IsNullOrEmpty(action))
47+
{
48+
Debug.LogWarning("[ActionController] 액션이 null입니다.");
49+
return;
50+
}
51+
52+
// 현재 액션이 재생 중이라면 중단
53+
if (_isActionPlaying)
54+
{
55+
StopCurrentAction();
56+
}
57+
58+
StartAction(action, args);
59+
}
60+
61+
#endregion
62+
63+
#region Public Methods
64+
65+
/// <summary>
66+
/// 현재 액션을 중단한다.
67+
/// </summary>
68+
public void StopCurrentAction()
69+
{
70+
if (_actionCoroutine != null)
71+
{
72+
StopCoroutine(_actionCoroutine);
73+
_actionCoroutine = null;
74+
}
75+
76+
_isActionPlaying = false;
77+
_currentAction = null;
78+
79+
Debug.Log("[ActionController] 액션 중단");
80+
}
81+
82+
/// <summary>
83+
/// 현재 액션을 반환한다.
84+
/// </summary>
85+
public string GetCurrentAction()
86+
{
87+
return _currentAction;
88+
}
89+
90+
/// <summary>
91+
/// 액션이 재생 중인지 확인한다.
92+
/// </summary>
93+
public bool IsActionPlaying()
94+
{
95+
return _isActionPlaying;
96+
}
97+
98+
#endregion
99+
100+
#region Private Methods
101+
102+
private void StartAction(string action, object args)
103+
{
104+
var motionKey = GetMotionKey(action);
105+
if (string.IsNullOrEmpty(motionKey))
106+
{
107+
Debug.LogWarning($"[ActionController] 액션 '{action}'에 대한 모션을 찾을 수 없습니다.");
108+
return;
109+
}
110+
111+
_actionCoroutine = StartCoroutine(ActionCoroutine(action, motionKey, args));
112+
}
113+
114+
private IEnumerator ActionCoroutine(string action, string motionKey, object args)
115+
{
116+
_currentAction = action;
117+
_isActionPlaying = true;
118+
119+
Debug.Log($"[ActionController] 액션 시작: {action}");
120+
121+
// 모션 재생 (현재는 더미 처리)
122+
PlayMotion(motionKey, args);
123+
124+
// 모션 지속 시간만큼 대기
125+
var duration = GetActionDuration(action);
126+
yield return new WaitForSeconds(duration);
127+
128+
// 액션 완료
129+
_isActionPlaying = false;
130+
_currentAction = null;
131+
132+
Debug.Log($"[ActionController] 액션 완료: {action}");
133+
}
134+
135+
private void PlayMotion(string motionKey, object args)
136+
{
137+
if (_motionController == null) return;
138+
139+
// TODO: 실제 모션 재생 로직 구현
140+
// 현재는 더미 처리로 로그만 출력
141+
Debug.Log($"[ActionController] 모션 재생: {motionKey}");
142+
143+
// 향후 구현 예정:
144+
// _motionController.PlayMotion(motionKey);
145+
// 또는
146+
// _motionController.PlayMotionGroup(motionKey);
147+
}
148+
149+
private string GetMotionKey(string action)
150+
{
151+
foreach (var mapping in _actionMappings)
152+
{
153+
if (mapping.Action.Equals(action, StringComparison.OrdinalIgnoreCase))
154+
{
155+
return mapping.MotionKey;
156+
}
157+
}
158+
159+
// 기본값 반환
160+
return "idle";
161+
}
162+
163+
private float GetActionDuration(string action)
164+
{
165+
foreach (var mapping in _actionMappings)
166+
{
167+
if (mapping.Action.Equals(action, StringComparison.OrdinalIgnoreCase))
168+
{
169+
return mapping.Duration > 0 ? mapping.Duration : _defaultMotionDuration;
170+
}
171+
}
172+
173+
return _defaultMotionDuration;
174+
}
175+
176+
#endregion
177+
178+
#region Action Mapping
179+
180+
[System.Serializable]
181+
public class ActionMotionMapping
182+
{
183+
public string Action;
184+
public string MotionKey;
185+
public float Duration;
186+
}
187+
188+
#endregion
189+
}
18190
}
19191

20192

0 commit comments

Comments
 (0)