본문 바로가기

Unity

[Unity] Localization : 다중언어 지원

게임을 개발하면 한국어버전/영어버전으로 여러가지 버전을 만들어야 할 일이 있다. 이럴때는 빌드를 따로 두번 하는것이 아니라 설정을 통해 언어를 정하고, 하나의 빌드본안에서 json파일을 읽어 게임내 텍스트의 언어를 바꾸도록한다.

 

오늘은 이 기능을 구현해보자!!

 

1. LocalizationData.cs

[System.Serializable]
public class LocalizationData
{
    public LocalizationItem[] items;
}

[System.Serializable]
public class LocalizationItem
{
    public string key;
    public string value;
}

 

이 클래스는 언어데이터를 담을 클래스이다.  Monobehaviour 을 상속받지않는다. LocalizationItem은 어떤 텍스트인지 구분하는 key와 실제 value로 이루어져있고, LocalizationData는 그 아이템들을 모아놓은 배열로 이루어져있다.

 

 

2.텍스트데이터를 저장해야한다. 다음 그림과같이 텍스트데이터를 저장하기 위한 폴더를 따로 생성한 뒤, json파일을 저장한다. 

 

 

3.LocalizationManager.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

public class LocalizationManager : MonoBehaviour
{

    public static LocalizationManager instance;
    private Dictionary<string, string> localizedText;
    private string missingTextString = "Localized text not found";


    // Start is called before the first frame update
    void Awake()
    {

        //싱글톤 패턴
        if(instance == null)
        {
            instance = this;
        }
        else if(instance != this)
        {
            Destroy(gameObject);
        }
        //DontDestroyOnLoad(gameObject);
    }

    public void LoadLocalizedText(string fileName)
    {
        localizedText = new Dictionary<string, string>();
        string filePath = Path.Combine(Application.streamingAssetsPath, fileName);
        filePath += ".txt";
        if (File.Exists(filePath))
        {
            string dataAsJson = File.ReadAllText(filePath); //json파일을 읽어서 string으로 뽑음
            LocalizationData loadedData = JsonUtility.FromJson<LocalizationData>(dataAsJson);    //deserialization

            //전체 아이템들에 대해서
            for (int i = 0; i < loadedData.items.Length; i++)
            {
                localizedText.Add(loadedData.items[i].key, loadedData.items[i].value);
            }

            //localizationText 데이터 불러오기 완료
            Debug.Log("Data loaded. Dictionary containts :" + localizedText.Count + " entries");

        }
        else
        {
            //파일이 존재하지않음
            Debug.LogError("Cannot find file"); 
        }

    }


    public string GetLocalizedValue(string key)
    {
        string result = missingTextString;
        if(localizedText.ContainsKey(key))
        {
            result = localizedText[key];
        }

        return result;
    }

}

 

LocalizationManager은 설정을 변경할 때 json파일로부터 텍스트데이터를 로드하고,key값을 주면 그에 대응되는 value를 반환하는 총 매니저 역할을 하는 스크립트이다. 씬 어디에서나 접근할수있도록 싱글톤 패턴을 사용한다. 인스턴스가 계속 살아있게 하기 위해서는 DontDestroyObject(gameObject) 를 추가해주면되지만, 나의경우 상위 오브젝트에서 이미 실행중이므로 이 스크립트에서는 생략했다.

json을 txt형식으로 저장한뒤,  Asset>StreamingAssets>LocalizedText_en.txt 로 저장해놓는다.

여기서 StreamingAssets 폴더는 로컬라이징을 위한 JSON텍스트들을 모아놓은 폴더이다

 

Asset>StreamingAssets
설정화면에서 언어를 변경할때

 

4.LocalizedText

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class LocalizedText : MonoBehaviour
{

    public string key;

    // Start is called before the first frame update
    void Start()
    {
        Text text = GetComponent<Text>();
        text.text = LocalizationManager.instance.GetLocalizedValue(key);
    }

}

 실제 텍스트의 컴포턴트로 붙여서 변환을 수행하는 스크립트이다. 텍스트마다 이 스크립트를 붙여야한다.

 

위 사진은 실제 설정페이지에서 언어선택버튼에 붙여주는 OnClick 메소드이다. 

번역을 원하는 text에 컴포넌트 붙여주기

마지막으로 번역이 필요한 텍스트마다 컴포넌트를 붙이고, 해당하는 key값을 넣어주면 완료!!

주의해야할점은, loadLocalizedText를 수행한뒤 텍스트를 켜야 Start()메소드에서 적용된다는것.