[unity] 모듈 제작 : Localization Manager 제작
Unity에서 GoogleSheet를 활용하여 현지화 언어 변환 모듈인 Localization Manager Class를 만들어 보자.
1. 구글 시트 생성 및 테이블 작성
- 구글 시트를 하나 생성한 후 간단한 테이블을 하나 만들어 준다.(구글시트 바로가기)
- 테스트를 위한 테이블 구조는 아래와 같다.
Korean | English | Japanese |
호랑이 | =GOOGLETRANSLATE(A2,"Ko","En") | =GOOGLETRANSLATE(B2,"Ko","ja") |
사자 | =GOOGLETRANSLATE(A3,"Ko","En") | =GOOGLETRANSLATE(B3,"Ko","ja") |
코끼리 | =GOOGLETRANSLATE(A4,"Ko","En") | =GOOGLETRANSLATE(B4,"Ko","ja") |
- 기본 베이스 언어는 한국어이며, 번역 텍스트인 영어와 일본어는 GOOGLETRANCLATE 함수를 이용하여, 자동 번역될 수 있도록 구성한다.
- 기본 Key 값은 한국어가 기준이 된다.
2. 유니티 사전 준비
- 스크립트 작성 전 Serialize Dictionary 를 사용하기 위해, 무료 에셋을 하나 추가해 주자.
- SerializableDictionary 에셋 추가는 기존 팝업 시스템에서 추가했던 에셋과 동일하다.
2022.05.24 - [unity3d/Modules] - [unity] 모듈 제작 : 팝업 시스템 만들기(1)
- Assets에 Modules 폴더를 만들고 안에 Localization 폴더를 만들어 Prefabs와 Scripts 폴더를 만들어 준다.
3. 유니티 스크립트 작성
- Scripts 폴더 안에 LocalizationManager.cs Class와 LocalizationText.cs를 만들고, Editor 폴더를 만들어, LocalizationManagerEditor.cs의 에디터 클래스를 하나 만든다.
- LocalizationManager.cs 클래스를 열어 아래와 같이 작성한다.
using System;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
namespace Container.Localization
{
[Serializable]
public class StringStringDictionary : SerializableDictionary<string, string> { }
[Serializable]
public class LanguageDictionary : SerializableDictionary<string, StringStringDictionary> { }
/// <summary>
/// 현지화를 위한 언어팩 매니저 클래스.
/// GoogleDoc을 파싱하여 사용.
/// </summary>
public class LocalizationManager : MonoBehaviour
{
protected string Language { get; private set; }
public static LocalizationManager Instance { get; private set; }
[SerializeField]
private string langURL = "https://docs.google.com/spreadsheets/d/1LeDydivi55yGxns9u_PP59C7PLwcKqdAiL2EnCQ_Imk/export?format=tsv";
[SerializeField]
private LanguageDictionary Langs;
void Awake()
{
Instance = this;
}
private void OnDestroy()
{
Instance = null;
}
private void Start()
{
//초기화는 시스템 기본 언어로 세팅한다.
Language = Application.systemLanguage.ToString();
}
public void GetLocalizationText()
{
Langs.Clear();
GetLanguage();
}
/// <summary>
/// GoogleSheet에서 데이터 가져오기
/// </summary>
/// <returns></returns>
private async Task GetLanguage()
{
UnityWebRequest request = UnityWebRequest.Get(langURL);
var op = await request.SendWebRequest();
SetLanguageList(op.downloadHandler.text);
}
/// <summary>
/// 행, 열 분리하여 Dictionary에 데이터 입력 함수
/// </summary>
/// <param name="text"></param>
private void SetLanguageList(string text)
{
string[] row = text.Split('\n');
int rowSize = row.Length;
int columnSize = row[0].Split('\t').Length;
string[,] Sentence = new string[rowSize, columnSize];
for (int i = 0; i < rowSize; i++)
{
string[] column = row[i].Split('\t');
for (int j = 0; j < columnSize; j++) Sentence[i, j] = column[j];
}
Langs = new LanguageDictionary();
for (int i = 1; i < rowSize; i++)
{
Langs.Add(Sentence[i, 0].TrimEnd(), new StringStringDictionary());
for (int j = 0; j < columnSize; j++)
{
Langs[Sentence[i, 0].TrimEnd()].Add(Sentence[0, j].TrimEnd(), Sentence[i, j]);
}
}
}
/// <summary>
/// Key값으로 언어 검색
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string GetText(string key)
{
if (Langs.ContainsKey(key))
{
if (Langs[key].ContainsKey(Language))
{
return Langs[key][Language];
}
else
{
//언어 키가 없을 경우, defalut로 영어 세팅.
if (Langs[key].ContainsKey("English"))
{
return Langs[key]["English"];
}
}
}
return key;
}
}
}
- 본인이 제작한 구글 시트 주소의 마지막 부분을 /edit#gid=0 에서 /export? format=tsv로 변경해줘야 한다.
- LocalizationManagerEditor.cs 클래스는 아래와 같이 작성 한다.
- 에디터에 버튼을 생성하고. 버튼을 누를 경우, LocalizationManager의 GetLocalizationText() 함수를 호출한다.
using UnityEngine;
using UnityEditor;
namespace Container.Localization
{
[CustomEditor(typeof(LocalizationManager))]
public class LocalizationManagerEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
LocalizationManager _target = (LocalizationManager)target;
if (GUILayout.Button("Get Localize Text"))
{
_target.GetLocalizationText();
EditorUtility.SetDirty(_target);
}
}
}
}
- LocalizationText.cs는 UIText 컴포넌트와 같이 붙는 컴포넌트다.
- UIText와 TextMeshPro Text를 지원한다.
- 아래와 같이 작성해 준다.
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace Container.Localization
{
public class LocalizationText : MonoBehaviour
{
private void Start()
{
if (LocalizationManager.Instance != null)
{
string curStr = string.Empty;
if(GetComponent<Text>())
{
curStr = GetComponent<Text>().text;
GetComponent<Text>().text = LocalizationManager.Instance.GetText(curStr);
}
if(GetComponent<TextMeshProUGUI>())
{
curStr = GetComponent<TextMeshProUGUI>().text;
GetComponent<TextMeshProUGUI>().text = LocalizationManager.Instance.GetText(curStr);
}
}
else
{
Debug.LogWarning("LocalizationManager is null - Please check if there is any containers");
}
}
}
}
4. Scene 구성
- Modules라는 Scene을 만든 후, Modules GameObject와 LocalizationManager GameObject를 생성한다.
- LocalizationManager의 GameObject에 LocalizationManager 스크립트는 붙여준다.
- Lang URL을 넣어준다.(구글 스프레드 시트 주소이며 끝에는 //export? format=tsv
5. Test 방법
- Get Localization Text 버튼을 눌러. 텍스트를 가져와 보자.
- Dictionary 형태로 잘 가져온 걸 확인할 수 있다.
- 언어가 변환돼야 할 UIText 및 TextMeshProUGUI 게임 오브젝트에 LocalizationText 컴포넌트를 붙여준다.
- 모바일에서 구동되면 핸드폰에서 SystemLanguage를 받아와 해당 언어로 변환해준다.
- 현지화 언어를 받아오는 부분은 LocalizationManager.Instance.GetText(key값); 통해서 받아올 수 있다.
(LocalizationText.cs 스크립트 참고)
- 주의할 점은 프로젝트에서 사용 중인 폰트(. ttf, .otf)가 해당 언어를 지원해줘야 한다.
댓글