Skip to content

Commit 322890f

Browse files
committed
feat: response 객체에 추가 데이터
1 parent f722557 commit 322890f

File tree

10 files changed

+116
-24
lines changed

10 files changed

+116
-24
lines changed

Assets/Domain/Character/Script/Service/ICharacterActionService.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,6 @@ public interface ICharacterActionService
3030
/// </summary>
3131
void StopAll();
3232

33-
/// <summary>
34-
/// 음성 게이트를 설정한다.
35-
/// </summary>
36-
/// <param name="isVoicePlaying">음성이 재생 중인지 여부</param>
37-
void SetVoiceGate(bool isVoicePlaying);
38-
3933
/// <summary>
4034
/// 현재 액션 상태를 반환한다.
4135
/// </summary>

Assets/Domain/Chat/Model/Actor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ public enum Actor
55
User,
66
Character
77
}
8-
}
8+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#nullable enable
2+
using UnityEngine;
3+
4+
namespace ProjectVG.Domain.Chat.Model
5+
{
6+
public class CharacterActionData
7+
{
8+
/// <summary>
9+
/// 캐릭터가 수행할 행동
10+
/// </summary>
11+
public string Action { get; set; } = string.Empty;
12+
13+
/// <summary>
14+
/// 행동 문자열로 초기화
15+
/// </summary>
16+
/// <param name="action">행동 문자열</param>
17+
public CharacterActionData(string? action = null)
18+
{
19+
Action = action ?? "talk";
20+
}
21+
22+
/// <summary>
23+
/// 행동이 설정되어 있는지 확인
24+
/// </summary>
25+
/// <returns>행동이 설정되어 있으면 true</returns>
26+
public bool HasAction() => !string.IsNullOrEmpty(Action);
27+
}
28+
}

Assets/Domain/Chat/Model/CharacterActionData.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.
Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#nullable enable
22
using System;
3-
using System.Collections.Generic;
43
using UnityEngine;
54
using ProjectVG.Infrastructure.Network.DTOs.Chat;
65

@@ -12,31 +11,41 @@ public class ChatMessage
1211
public string SessionId { get; set; } = string.Empty;
1312
public string? Text { get; set; }
1413
public VoiceData? VoiceData { get; set; }
14+
public CharacterActionData? ActionData { get; set; }
15+
public CostInfo? CostInfo { get; set; }
1516
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
16-
public Dictionary<string, object>? Metadata { get; set; }
1717

1818
public static ChatMessage FromChatResponse(ChatResponse response)
1919
{
20-
var chatMessage = new ChatMessage
21-
{
20+
var chatMessage = new ChatMessage {
2221
SessionId = response.SessionId,
2322
Text = response.Text,
2423
Timestamp = response.Timestamp,
25-
Metadata = response.Metadata
24+
ActionData = new CharacterActionData(response.Action)
2625
};
2726

2827
if (!string.IsNullOrEmpty(response.AudioData))
2928
{
3029
chatMessage.VoiceData = VoiceData.FromBase64(response.AudioData, response.AudioFormat);
3130
}
3231

32+
if ((response.UsedCost ?? 0) > 0 || (response.RemainingCost ?? 0) > 0)
33+
{
34+
chatMessage.CostInfo = new CostInfo(response.UsedCost ?? 0f, response.RemainingCost ?? 0f);
35+
}
36+
3337
return chatMessage;
3438
}
3539

3640
public bool HasVoiceData() => VoiceData != null && VoiceData.IsPlayable();
3741

3842
public bool HasTextData() => !string.IsNullOrEmpty(Text);
43+
44+
public bool HasActionData() => ActionData != null && ActionData.HasAction();
45+
46+
public bool HasCostInfo() => CostInfo != null && CostInfo.HasCostInfo();
3947

4048
public AudioClip? GetAudioClip() => VoiceData?.AudioClip;
49+
4150
}
4251
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#nullable enable
2+
using System;
3+
4+
namespace ProjectVG.Domain.Chat.Model
5+
{
6+
7+
[Serializable]
8+
public class CostInfo
9+
{
10+
11+
public float UsedCost { get; set; } = 0f;
12+
13+
public float RemainingCost { get; set; } = 0f;
14+
15+
public CostInfo() { }
16+
17+
public CostInfo(float usedCost, float remainingCost)
18+
{
19+
UsedCost = usedCost;
20+
RemainingCost = remainingCost;
21+
}
22+
23+
public bool HasCostInfo() => UsedCost > 0 || RemainingCost > 0;
24+
25+
26+
public override string ToString()
27+
{
28+
return $"Used: {UsedCost} Token, Remaining: {RemainingCost} Token";
29+
}
30+
}
31+
}

Assets/Domain/Chat/Model/CostInfo.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/Chat/Model/VoiceData.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ public VoiceData(AudioClip audioClip, float length, string format = "wav")
1717
Format = format;
1818
}
1919

20-
public VoiceData()
21-
{
22-
}
23-
2420
public static VoiceData FromBase64(string base64Data, string format = "wav")
2521
{
2622
if (string.IsNullOrEmpty(base64Data))

Assets/Domain/Chat/Service/ChatSystemManager.cs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class ChatSystemManager : MonoBehaviour
3636
public bool IsInitialized => _isInitialized;
3737

3838
public event Action<string>? OnError;
39+
public event Action? OnConversationEnd;
3940

4041
#region Unity Lifecycle
4142

@@ -174,23 +175,46 @@ public void ProcessCharacterMessage(ChatMessage chatMessage)
174175
private async UniTask ProcessMessageAsync(ChatMessage chatMessage)
175176
{
176177
try {
177-
178178
if (_chatBubblePanel != null && !string.IsNullOrEmpty(chatMessage.Text)) {
179179
_chatBubblePanel.CreateBubble(Actor.Character, chatMessage.Text);
180180
}
181181

182-
// TODO : 캐릭터 반응을 전달한다.
182+
// TODO : 캐릭터 반응을 전달한다
183+
183184

184185
if (chatMessage.VoiceData != null && _audioManager != null) {
185-
await _audioManager.PlayVoiceAsync(chatMessage.VoiceData);
186+
_audioManager.PlayVoiceAsync(chatMessage.VoiceData).Forget();
186187
}
188+
189+
float waitTime = CalculateConversationWaitTime(chatMessage);
190+
await UniTask.Delay((int)(waitTime * 1000));
191+
192+
OnConversationEnd?.Invoke();
187193
}
188194
catch (Exception ex) {
189195
Debug.LogError($"[ChatSystemManager] 캐릭터 메시지 처리 실패: {ex.Message}");
190196
OnError?.Invoke($"메시지 처리 실패: {ex.Message}");
191197
}
192198
}
193199

200+
/// <summary>
201+
/// 대화 대기 시간을 계산한다
202+
/// </summary>
203+
private float CalculateConversationWaitTime(ChatMessage chatMessage)
204+
{
205+
float baseTime = 0f;
206+
207+
if (chatMessage.VoiceData != null && chatMessage.VoiceData.IsPlayable()) {
208+
baseTime = chatMessage.VoiceData.Length;
209+
}
210+
211+
if (baseTime <= 0f) {
212+
baseTime = 2f;
213+
}
214+
215+
return baseTime + 0.5f;
216+
}
217+
194218
private bool ValidateUserInput(string message)
195219
{
196220
if (string.IsNullOrWhiteSpace(message)) {

Assets/Infrastructure/Network/DTOs/Chat/ChatResponse.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ public class ChatResponse
1919

2020
[JsonProperty("text")]
2121
public string? Text { get; set; }
22-
22+
23+
[JsonProperty("action")]
24+
public string? Action { get; set; }
25+
2326
[JsonProperty("audio_data")]
2427
public string? AudioData { get; set; }
2528

@@ -28,11 +31,14 @@ public class ChatResponse
2831

2932
[JsonProperty("audio_length")]
3033
public float? AudioLength { get; set; }
31-
34+
35+
[JsonProperty("used_cost")]
36+
public float? UsedCost { get; set; }
37+
38+
[JsonProperty("remaining_cost")]
39+
public float? RemainingCost { get; set; }
40+
3241
[JsonProperty("timestamp")]
3342
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
34-
35-
[JsonProperty("metadata")]
36-
public Dictionary<string, object>? Metadata { get; set; }
3743
}
3844
}

0 commit comments

Comments
 (0)