
안녕하세요?
오늘은 Localication 활용 중 Format String 방법을 쓰는 방법에 대해 배워보겠습니다.

사진은 구글 시트에서 작성한 Localize Table인데요. 구글 시트에서 한국어 대사를 적용하면 Translation 함수로 한번에 영어로 번역하고 pull을 통해 유니티로 끌고 올 수 있다고 지난 게시글에서 배웠었죠.
[Unity] Localization, 구글시트 연동하기
그 Localization Table에서 중간에 변하는 데이터를 넣고 싶다면 어떻게 해야 할까요?
(저는 대사 중간에 PlayerPrefs로 저장된 플레이어의 이름과 등장인물의 한/영 버전 이름을 넣고 싶었습니다.)
Smart String으로 할수도 있나요? 저는 처음에 시도했지만 그 방법을 실패하고 다른 방법으로 해냈습니다.
format string 방법입니다.
언어를 공부해보신 분들은 익숙한 방법일 겁니다.
문자열 안에 {0}, {1} 같은 자리 표시자를 넣고, 실제 값을 순서대로 전달하는 방법이죠.
먼저 Localization Table에 위 사진과 같이 format 방식으로({0}, {1}과 같이) 대사를 입력해줍니다.
IEnumerator ShowDialogue(TextMeshProUGUI textUI, string key)
{
var localizedString = new LocalizedString(tableName, key);
var docNameString = new LocalizedString("LocalTable", "오랑이");
var beastNameString = new LocalizedString("LocalTable", "짐승덕기");
var crewNameString = new LocalizedString("LocalTable", "활주미란");
bool done = false;
bool beastDone = false;
bool crewDone = false;
bool docDone = false;
string docName = null;
string beastName = null;
string crewName = null;
string playerName = PlayerPrefs.GetString("Name", "DefaultName");
docNameString.StringChanged += (value) => { docName = value; docDone = true; };
while (!docDone)
yield return null;
beastNameString.StringChanged += (value) => { beastName = value; beastDone = true; };
while (!beastDone)
yield return null;
crewNameString.StringChanged += (value) => { crewName = value; crewDone = true; };
while (!crewDone)
yield return null;
localizedString.Arguments = new List<object>() { docName, crewName, beastName, playerName };
localizedString.StringChanged += (value) =>
{
textUI.text = $"{value}";
done = true;
};
while (!done)
yield return null;
}
localizedString.Arguments = new List<object>() { docName, crewName, beastName, playerName };
위 코드에서 쓴 docName, crewName, beastName, playerName이 차례로 테이블에서 작성한 대사의 {0}, {1}, {2}, {3}에 해당할 거라는 걸 눈치채실 수 있겠죠?
var로 가져온 어쩌구NameString은 LocalizedString 객체라서 바로 {n}에 들어갈 수 없습니다. 반드시 .StringChanged와 같은 방법으로 문자열을 받아야 합니다.
localizedString.Arguments의 Arguments에는 실제 문자열이 들어가야 해요.
즉, var 객체의 값을 먼저 가져와야 합니다.
그 방법은 .StringChanged를 통해 값(string)을 가져오는 것입니다.
LocalizedString.StringChanged를 설명해보자면 로컬라이즈된 문자열이 준비되었을 때 알림을 받는 이벤트입니다.
Unity Localization에서 로컬라이즈된 문자열은 즉시 가져올 수 없고, 내부적으로 비동기로 로딩되기 때문에 바로 값이 안 나올 수 있습니다. 그래서 StringChanged 이벤트를 써서 값이 준비되면 처리해야 하는 거죠.
StringChanged는 비동기 이벤트라 코루틴에서 yield로 기다려야 실제 문자열을 안전하게 사용할 수 있어요.
따라서
bool docDone = false;
docNameString.StringChanged += (value) => { docName = value; docDone = true; };
while (!docDone)
yield return null;
이런 형태로 값이 준비될 때까지 기다려줍니다.
로컬라이즈된 문자열이 준비가 되면 우리는 Localize Table에 있는 데이터를 (객체->값으로 바꿨기 때문에) Arguments에 집어넣을 수 있고, format 방식으로 화면에 띄울 수가 있게 되는 겁니다!
StartCouroutine(ShowDialogue(TextMeshProUGUI textUI, string key));을 사용하면 바로 대사를 정상적으로 띄울 수 있게 됩니다 ~

{1}: "{0} 의사선생님이 쓰러졌어요! {2} 선생님을 불러주세요!"의 영어버전인
{1}: "Doctor {0} has collapsed! Please call Doctor {2}!"
이 정상적으로 나타난 모습입니다. ^^
localizedString.Arguments = new List<object>() { docName, crewName, beastName, playerName }; 순서대로 작성한 값이 대사에 들어갑니다.
자 오늘은 Localication 활용 중 Format String 방법을 쓰는 방법에 대해 알아보았는데요. 이 정도라면 Localization을 통해 웬만한 대사의 다중언어 적용은 가능할 것으로 보여집니다.
저는 Smart String을 꼭 자유자재로 쓰고 싶은데 (banana=1이라면 banana로 출력되고, 2이상이라면 bananas로 출력하는 게 멋있어보입니다.)
아직 많이 부족하고 어렵네요.
그래도 포기하지 않고 열심히 해볼겁니다~ 파이팅!