smart string 현지화 시스템 연동 및 글로벌 메세지 이벤트 기능 변경
This commit is contained in:
parent
2ec3ec58f9
commit
d5f72c3e4c
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
@ -56,6 +57,17 @@ public class ShowGlobalMessageEvent : IEvent
|
|||||||
public string NewMessageKey;
|
public string NewMessageKey;
|
||||||
public float ShowDuration;
|
public float ShowDuration;
|
||||||
public float FadeDuration;
|
public float FadeDuration;
|
||||||
|
public Color TextColor;
|
||||||
|
public int FontSize;
|
||||||
|
|
||||||
|
public void Set(string newMessageKey, float newShowDuration = 1f, float newFadeDuration = 0.5f, Color newTextColor = default, int fontSize = 44)
|
||||||
|
{
|
||||||
|
NewMessageKey = newMessageKey;
|
||||||
|
ShowDuration = newShowDuration;
|
||||||
|
FadeDuration = newFadeDuration;
|
||||||
|
TextColor = newTextColor == default ? Color.red : newTextColor;
|
||||||
|
FontSize = fontSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class OpenPopupUiEvent : IEvent
|
public class OpenPopupUiEvent : IEvent
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Localization;
|
using UnityEngine.Localization;
|
||||||
|
using UnityEngine.Localization.SmartFormat.PersistentVariables;
|
||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
@ -16,6 +17,8 @@ public class LocalizationManager : Singleton<LocalizationManager>, IManager
|
|||||||
private const string Name = "_name";
|
private const string Name = "_name";
|
||||||
private const string Description = "_description";
|
private const string Description = "_description";
|
||||||
|
|
||||||
|
private readonly List<object> _singleArgBuffer = new(1);
|
||||||
|
|
||||||
public async void PreInit()
|
public async void PreInit()
|
||||||
{
|
{
|
||||||
_localizedCache.Clear();
|
_localizedCache.Clear();
|
||||||
@ -83,15 +86,30 @@ public LocalizedString GetLocalizedString(string key)
|
|||||||
public LocalizedString GetLocalizedDescription(string key) => GetLocalizedString(key + Description);
|
public LocalizedString GetLocalizedDescription(string key) => GetLocalizedString(key + Description);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Key값 자체를 탐색
|
/// 현재 로케일 기준 동기 문자열 반환 (스마트 문자열 인자 지원)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string GetString(string key)
|
public string GetString(string key)
|
||||||
{
|
{
|
||||||
var localizedString = GetLocalizedString(key);
|
var localizedString = GetLocalizedString(key);
|
||||||
return LocalizationSettings.StringDatabase.GetLocalizedString(localizedString.TableReference, key, LocalizationSettings.SelectedLocale);
|
if (localizedString == null) return key; // fallback
|
||||||
|
|
||||||
|
var tableRef = localizedString.TableReference;
|
||||||
|
var entryRef = key;
|
||||||
|
var locale = LocalizationSettings.SelectedLocale;
|
||||||
|
|
||||||
|
VariablesGroupAsset variables = SmartStringVariables.Instance.GetVariablesGroupAsset();
|
||||||
|
if (variables != null)
|
||||||
|
{
|
||||||
|
_singleArgBuffer.Clear();
|
||||||
|
_singleArgBuffer.Add(variables); // SmartFormat이 {name}을 variables에서 찾음
|
||||||
|
return LocalizationSettings.StringDatabase.GetLocalizedString(tableRef, key, _singleArgBuffer, locale);
|
||||||
}
|
}
|
||||||
public string GetName(string key) => GetString(key + Name);
|
|
||||||
public string GetDescription(string key) => GetString(key + Description);
|
// 인자 없음
|
||||||
|
return LocalizationSettings.StringDatabase.GetLocalizedString(tableRef, entryRef, locale);
|
||||||
|
}
|
||||||
|
public string GetName(string key, VariablesGroupAsset variables = null) => GetString(key + Name);
|
||||||
|
public string GetDescription(string key, VariablesGroupAsset variables = null) => GetString(key + Description);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 현재 사용 중인 로케일 코드 반환 (예: "ko", "en", "ja")
|
/// 현재 사용 중인 로케일 코드 반환 (예: "ko", "en", "ja")
|
||||||
|
@ -0,0 +1,107 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Localization.SmartFormat.PersistentVariables;
|
||||||
|
|
||||||
|
namespace DDD
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Smart String 변수 전담 매니저.
|
||||||
|
/// - VariablesGroupAsset 안의 변수들을 생성/재사용하고 값만 갱신(무가비지).
|
||||||
|
/// - {day}, {playerName}, {money} 등 공용 Set API 제공.
|
||||||
|
/// </summary>
|
||||||
|
public class SmartStringVariables : Singleton<SmartStringVariables>, IManager
|
||||||
|
{
|
||||||
|
private VariablesGroupAsset _vars;
|
||||||
|
private GameStateSo _gameStateSo;
|
||||||
|
|
||||||
|
private const string VariablesGroupAssetKey = "SmartStringGroup";
|
||||||
|
private const string Daykey = "day";
|
||||||
|
|
||||||
|
public void PreInit() { }
|
||||||
|
|
||||||
|
public async Task Init()
|
||||||
|
{
|
||||||
|
_vars = await AssetManager.LoadAsset<VariablesGroupAsset>(VariablesGroupAssetKey);
|
||||||
|
Debug.Assert(_vars != null, "_variablesGroupAsset is null");
|
||||||
|
|
||||||
|
_gameStateSo = await AssetManager.LoadAsset<GameStateSo>(DataConstants.GameStateSo);
|
||||||
|
Debug.Assert(_gameStateSo != null, "_gameStateSo is null");
|
||||||
|
|
||||||
|
// 예시: day 초기 세팅 (없으면 생성, 타입 다르면 교체)
|
||||||
|
Set(Daykey, _gameStateSo.GetCurrentLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostInit() { }
|
||||||
|
|
||||||
|
public VariablesGroupAsset GetVariablesGroupAsset() => _vars;
|
||||||
|
|
||||||
|
// ---------- 공용 Set API (가비지 최소화) ----------
|
||||||
|
|
||||||
|
/// <summary>int 변수 세팅. {key} 로 접근.</summary>
|
||||||
|
public void Set(string key, int value)
|
||||||
|
{
|
||||||
|
var v = Ensure<IntVariable>(key);
|
||||||
|
if (v.Value != value) v.Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>float 변수 세팅. {key} 로 접근.</summary>
|
||||||
|
public void Set(string key, float value)
|
||||||
|
{
|
||||||
|
var v = Ensure<FloatVariable>(key);
|
||||||
|
if (!Mathf.Approximately(v.Value, value)) v.Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>bool 변수 세팅. {key} 로 접근.</summary>
|
||||||
|
public void Set(string key, bool value)
|
||||||
|
{
|
||||||
|
var v = Ensure<BoolVariable>(key);
|
||||||
|
if (v.Value != value) v.Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>string 변수 세팅. {key} 로 접근.</summary>
|
||||||
|
public void Set(string key, string value)
|
||||||
|
{
|
||||||
|
var v = Ensure<StringVariable>(key);
|
||||||
|
if (!string.Equals(v.Value, value)) v.Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// enum은 보통 현지화 포맷에서 문자열로 취급하는 편이 직관적입니다.
|
||||||
|
/// 필요시 IntVariable로 바꾸고 (int)(object)value 저장하는 버전도 추가 가능.
|
||||||
|
/// </summary>
|
||||||
|
public void SetEnum<TEnum>(string key, TEnum value) where TEnum : struct
|
||||||
|
{
|
||||||
|
var v = Ensure<StringVariable>(key);
|
||||||
|
string s = value.ToString();
|
||||||
|
if (!string.Equals(v.Value, s)) v.Value = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- 유틸 ----------
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// key에 해당하는 변수가 있고 타입이 일치하면 캐시 반환.
|
||||||
|
/// 없거나 타입이 다르면 교체(Add/Remove)하여 보장.
|
||||||
|
/// </summary>
|
||||||
|
private T Ensure<T>(string key) where T : class, IVariable, new()
|
||||||
|
{
|
||||||
|
Debug.Assert(!string.IsNullOrEmpty(key), "SmartStringVariables.Ensure: key is null or empty.");
|
||||||
|
Debug.Assert(_vars != null, "SmartStringVariables.Ensure: _vars is null (Init 순서 확인).");
|
||||||
|
|
||||||
|
if (_vars.TryGetValue(key, out var existing))
|
||||||
|
{
|
||||||
|
if (existing is T ok) return ok;
|
||||||
|
_vars.Remove(key); // 타입 다르면 제거 후 교체
|
||||||
|
}
|
||||||
|
|
||||||
|
var created = new T();
|
||||||
|
_vars.Add(key, created);
|
||||||
|
return (T)created;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>변수 존재 여부.</summary>
|
||||||
|
public bool Has(string key) => _vars != null && _vars.ContainsKey(key);
|
||||||
|
|
||||||
|
/// <summary>변수 제거.</summary>
|
||||||
|
public bool Remove(string key) => _vars != null && _vars.Remove(key);
|
||||||
|
}
|
||||||
|
}
|
@ -50,7 +50,11 @@ private void TryDisplayNext()
|
|||||||
var evt = _messageQueue.Dequeue();
|
var evt = _messageQueue.Dequeue();
|
||||||
_isDisplayingMessage = true;
|
_isDisplayingMessage = true;
|
||||||
|
|
||||||
_messageText.text = LocalizationManager.Instance.GetString(evt.NewMessageKey);
|
_messageText.color = evt.TextColor;
|
||||||
|
_messageText.fontSize = evt.FontSize;
|
||||||
|
|
||||||
|
string localized = LocalizationManager.Instance.GetString(evt.NewMessageKey);
|
||||||
|
_messageText.text = localized;
|
||||||
OpenPanel();
|
OpenPanel();
|
||||||
|
|
||||||
_fadeTween?.Kill();
|
_fadeTween?.Kill();
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
public class TodayMenuInteractorStrategy : IItemSlotInteractorStrategy
|
public class TodayMenuInteractorStrategy : IItemSlotInteractorStrategy
|
||||||
@ -14,9 +16,7 @@ public void OnAdded(ItemSlotUi itemSlotUi, RestaurantManagementSo restaurantMana
|
|||||||
{
|
{
|
||||||
var evt = GameEvents.ShowGlobalMessageEvent;
|
var evt = GameEvents.ShowGlobalMessageEvent;
|
||||||
// TODO : 테스트용 메세지 추후 삭제 및 변경
|
// TODO : 테스트용 메세지 추후 삭제 및 변경
|
||||||
evt.NewMessageKey = "today_menu_added_error_message_001";
|
evt.Set("today_menu_added_error_message_001");
|
||||||
evt.FadeDuration = 0.5f;
|
|
||||||
evt.ShowDuration = 1f;
|
|
||||||
EventBus.Broadcast(evt);
|
EventBus.Broadcast(evt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
public class TodayCookwareInteractorStrategy : IItemSlotInteractorStrategy
|
public class TodayCookwareInteractorStrategy : IItemSlotInteractorStrategy
|
||||||
@ -14,9 +16,7 @@ public void OnAdded(ItemSlotUi itemSlotUi, RestaurantManagementSo restaurantMana
|
|||||||
{
|
{
|
||||||
var evt = GameEvents.ShowGlobalMessageEvent;
|
var evt = GameEvents.ShowGlobalMessageEvent;
|
||||||
// TODO : 테스트용 메세지 추후 삭제 및 변경
|
// TODO : 테스트용 메세지 추후 삭제 및 변경
|
||||||
evt.NewMessageKey = "today_menu_added_error_message_001";
|
evt.Set("today_menu_added_error_message_001");
|
||||||
evt.FadeDuration = 0.5f;
|
|
||||||
evt.ShowDuration = 1f;
|
|
||||||
EventBus.Broadcast(evt);
|
EventBus.Broadcast(evt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ public class RestaurantController : Singleton<RestaurantController>, IManager, I
|
|||||||
|
|
||||||
private const string CreateRestaurantPlayerSo = "CreateRestaurantPlayerSo";
|
private const string CreateRestaurantPlayerSo = "CreateRestaurantPlayerSo";
|
||||||
private const string CreateEnvironmentSo = "CreateEnvironmentSo";
|
private const string CreateEnvironmentSo = "CreateEnvironmentSo";
|
||||||
|
private const string ReadyForRestaurantMessageKey = "ready_for_restaurant_message";
|
||||||
|
private const string RunRestaurantMessageKey = "run_restaurnat_message";
|
||||||
|
|
||||||
public void PreInit()
|
public void PreInit()
|
||||||
{
|
{
|
||||||
@ -75,12 +77,20 @@ public async Task OnReadyNewFlow(GameFlowState newFlowState)
|
|||||||
// Combine handles and return it
|
// Combine handles and return it
|
||||||
InputManager.Instance.SwitchCurrentActionMap(InputActionMaps.Restaurant);
|
InputManager.Instance.SwitchCurrentActionMap(InputActionMaps.Restaurant);
|
||||||
await Task.WhenAll(playerHandle, todayMenuHandle);
|
await Task.WhenAll(playerHandle, todayMenuHandle);
|
||||||
|
|
||||||
|
var evt = GameEvents.ShowGlobalMessageEvent;
|
||||||
|
evt.Set(ReadyForRestaurantMessageKey, newShowDuration:3f, newTextColor:Color.yellow, fontSize:60);
|
||||||
|
EventBus.Broadcast(evt);
|
||||||
}
|
}
|
||||||
else if (newFlowState == GameFlowState.RunRestaurant)
|
else if (newFlowState == GameFlowState.RunRestaurant)
|
||||||
{
|
{
|
||||||
var restaurantCustomerStateHandle = RestaurantCustomerStateSo.OnReadyNewFlow(newFlowState);
|
var restaurantCustomerStateHandle = RestaurantCustomerStateSo.OnReadyNewFlow(newFlowState);
|
||||||
|
|
||||||
await Task.WhenAll(restaurantCustomerStateHandle);
|
await Task.WhenAll(restaurantCustomerStateHandle);
|
||||||
|
|
||||||
|
var evt = GameEvents.ShowGlobalMessageEvent;
|
||||||
|
evt.Set(RunRestaurantMessageKey, newShowDuration:3f, newTextColor:Color.yellow, fontSize:60);
|
||||||
|
EventBus.Broadcast(evt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user