https://github.com/kastro723/LocalizationEditor
+++
using UnityEngine;
using UnityEngine.UI;
public class TestLocalization : MonoBehaviour
{
[SerializeField] private Button[] changeLanBtns;
[SerializeField] private Button getValue;
void Start()
{
string Test1 = LocalizationManager.instance.GetLocalString(LocalizationConstants.TROPHY_POPUP_TITLE_FOR_UNLOCK);
Debug.Log(Test1);
changeLanBtns[0].onClick.AddListener(() => LocalizationManager.instance.SetLanguage("kr"));
changeLanBtns[1].onClick.AddListener(() => LocalizationManager.instance.SetLanguage("en"));
changeLanBtns[2].onClick.AddListener(() => LocalizationManager.instance.SetLanguage("jp"));
getValue.onClick.AddListener(() =>
{
string value = LocalizationManager.instance.GetLocalString(LocalizationConstants.TROPHY_POPUP_TITLE_FOR_UNLOCK);
Debug.Log(value);
});
}
}
테스트 해본 스크립트
public interface ILocalization
{
string GetLocalString(string key);
}
ILocalization.cs
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using ExcelDataReader;
using System.Data;
public class LocalizationManager : ILocalization
{
public static readonly LocalizationManager instance = new LocalizationManager();
private string language;
private Dictionary<string, string> dicLocalizationData;
private LocalizationManager()
{
dicLocalizationData = new Dictionary<string, string>();
Init();
}
public void Init() // 초기 설정
{
// 기기의 기본 언어 설정을 가져옴
SystemLanguage systemLanguage = Application.systemLanguage;
string defaultLanguage = ConvertSystemLanguageToCode(systemLanguage); // 기기의 시스템 언어를 언어 코드로 변환
language = PlayerPrefsManager.Instance.GetString("Language", defaultLanguage); // 사용자가 설정한 언어가 없다면 기기의 기본 언어를 사용
PlayerPrefsManager.Instance.SetString("Language", language); // 현재 언어 설정을 저장
Debug.Log("current language: " + language);
LoadLocalizationData();
}
private string ConvertSystemLanguageToCode(SystemLanguage language)
{
switch (language)
{
case SystemLanguage.Korean:
return "kr";
case SystemLanguage.English:
return "en";
case SystemLanguage.Japanese:
return "jp";
default:
return "kr"; // 기본값으로 한국어 설정
}
}
private void LoadLocalizationData()
{
string filePath = LocalizationConstants.excelFilePath; // LocalizationConstants.cs에서 정의된 경로를 사용
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
{
using (var reader = ExcelReaderFactory.CreateReader(stream))
{
var result = reader.AsDataSet();
DataTable table = result.Tables[0];
// 언어 코드는 1행 2열 부터 위치함.
var languageCodes = new List<string>();
for (int columnIndex = 1; columnIndex < table.Columns.Count; columnIndex++)
{
languageCodes.Add(table.Rows[0][columnIndex].ToString()); // 1행 2열부터 언어 코드를 읽음
}
// 데이터는 3행부터 시작합니다.
for (int rowIndex = 2; rowIndex < table.Rows.Count; rowIndex++)
{
var row = table.Rows[rowIndex];
string key = row[0].ToString(); // 첫 번째 열은 키 값입니다.
for (int columnIndex = 1; columnIndex < languageCodes.Count + 1; columnIndex++)
{
string languageCode = languageCodes[columnIndex - 1]; // 언어 코드 리스트에서 언어 코드를 가져옴
string value = row[columnIndex].ToString();
string dicKey = $"{key}_{languageCode}".ToUpper(); // 복합 키 생성 (예: TROPHY_POPUP_TITLE_FOR_UNLOCK_KR)
dicLocalizationData[dicKey] = value; // 딕셔너리에 언어별 값 저장
}
}
}
}
}
public void SetLanguage(string lan) // 언어 변경
{
language = lan;
language = language.ToLower(); // 대, 소문자를 소문자로 통합
if (language == "kr" || language == "en" || language == "jp") // 언어 추가 시, 조건 추가
{
PlayerPrefsManager.Instance.SetString("Language", language); // 현재 언어 설정을 저장, (kr, en, jp)
Debug.Log("current language: " + language);
dicLocalizationData.Clear();
LoadLocalizationData();
}
else
{
Debug.Log("Language Invaild Input!");
}
}
/// <summary>
/// 언어별로 로컬라이즈된 문자열을 반환.
/// </summary>
/// <param name="key">로컬라이제이션 키 (예: "TROPHY_POPUP_TITLE_FOR_UNLOCK")</param>
/// <returns>
/// 현재 설정된 언어에 맞는 로컬라이즈된 문자열.
/// 설정된 언어에 해당하는 문자열이 없을 경우 "Key {key} not found" 반환.
/// </returns>
/// <example>
/// // 사용법 예시:
/// string localizedText = LocalizationManager.instance.GetLocalString("TROPHY_POPUP_TITLE_FOR_UNLOCK");
/// Debug.Log(localizedText); // 현재 언어가 "kr"이라면 "잠금해제!"를 출력
/// </example>
public string GetLocalString(string key)
{
string dicKey = $"{key}_{language}".ToUpper();
if (dicLocalizationData.TryGetValue(dicKey, out string value))
{
return value;
}
return $"Key {key} not found";
}
}
LocalizationManager.cs
using UnityEditor;
using UnityEngine;
using System.IO;
using ExcelDataReader;
using System.Data;
using System.Text;
public class LocalizationEditor : EditorWindow
{
private string excelFilePath = string.Empty;
private string classFilePath = string.Empty;
[MenuItem("Tools/LocalizationEditor")]
public static void ShowWindow()
{
var window = GetWindow(typeof(LocalizationEditor));
window.maxSize = new Vector2(495, window.maxSize.y);
window.minSize = new Vector2(495, 300);
window.Show();
}
void OnGUI()
{
GUILayout.Label("Ver. 1.0.0", EditorStyles.boldLabel);
DrawLine();
// 드래그 앤 드롭 영역 생성
var dragArea = GUILayoutUtility.GetRect(0f, 100f, GUILayout.ExpandWidth(true));
GUI.Box(dragArea, "Drag & Drop Excel file here or Click 'Generate Constants Class'");
if (dragArea.Contains(Event.current.mousePosition) && Event.current.type == EventType.DragUpdated)
{
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
Event.current.Use();
}
else if (dragArea.Contains(Event.current.mousePosition) && Event.current.type == EventType.DragPerform)
{
DragAndDrop.AcceptDrag();
foreach (var dragged_object in DragAndDrop.objectReferences)
{
var path = AssetDatabase.GetAssetPath(dragged_object);
if (!string.IsNullOrEmpty(path) && path.EndsWith(".xlsx"))
{
excelFilePath = path;
// 새로운 .xlsx 파일이 선택될 때 기존 경로 초기화
classFilePath = "";
break;
}
}
Event.current.Use();
}
if (GUILayout.Button("Generate Constants Class") && !string.IsNullOrEmpty(excelFilePath))
{
GenerateConstantsClass(excelFilePath);
}
DrawLine();
GUILayout.BeginHorizontal();
GUILayout.Label("Selected Excel File: ", GUILayout.ExpandWidth(false));
GUI.enabled = false;
GUILayout.TextField(excelFilePath, GUILayout.ExpandWidth(true));
GUI.enabled = true;
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Cs Save Path: ", GUILayout.ExpandWidth(false));
GUI.enabled = false;
GUILayout.TextField(classFilePath, GUILayout.ExpandWidth(true));
GUI.enabled = true;
GUILayout.EndHorizontal();
}
private void GenerateConstantsClass(string path)
{
StringBuilder classBuilder = new StringBuilder();
classBuilder.AppendLine("using System.Collections;");
classBuilder.AppendLine("using System.Collections.Generic;");
classBuilder.AppendLine("using UnityEngine;");
classBuilder.AppendLine();
classBuilder.AppendLine("public class LocalizationConstants");
classBuilder.AppendLine("{");
classBuilder.AppendLine();
classBuilder.AppendLine($" public static string excelFilePath = \"{excelFilePath}\";");
classBuilder.AppendLine();
using (var stream = File.Open(path, FileMode.Open, FileAccess.Read))
{
using (var reader = ExcelReaderFactory.CreateReader(stream))
{
DataTable table = reader.AsDataSet().Tables[0];
for (int i = 2; i < table.Rows.Count; i++) // 데이터 행 시작 (3행부터)
{
string key = table.Rows[i][0].ToString().ToUpper();
string value = table.Rows[i][0].ToString();
classBuilder.AppendLine($" public const string {key} = \"{value}\";");
}
}
}
classBuilder.AppendLine("}");
classFilePath = EditorUtility.OpenFolderPanel("Select Folder to Save Class", "Assets", "");
if (!string.IsNullOrEmpty(classFilePath))
{
string targetFilePath = Path.Combine(classFilePath, "LocalizationConstants.cs");
// 파일이 이미 존재하는지 확인
if (File.Exists(targetFilePath))
{
if (EditorUtility.DisplayDialog("File Exists", "The file already exists. Do you want to overwrite it?", "Yes", "No"))
{
// yes를 선택하면 덮어쓰기
WriteToFile(targetFilePath, classBuilder.ToString());
EditorUtility.DisplayDialog("Success", "Class file has been successfully overwritten.", "OK");
}
// no를 선택하면 아무것도 하지 않음
}
else
{
// 파일이 존재하지 않으면 바로 쓰기
WriteToFile(targetFilePath, classBuilder.ToString());
EditorUtility.DisplayDialog("Success", "Class file has been successfully generated.", "OK");
}
}
}
private void WriteToFile(string filePath, string content)
{
File.WriteAllText(filePath, content);
AssetDatabase.Refresh();
}
private void DrawLine()
{
var rect = GUILayoutUtility.GetRect(1, 1, GUILayout.ExpandWidth(true));
EditorGUI.DrawRect(rect, Color.gray);
}
}
LocalizationEditor.cs
'UnityDataTools' 카테고리의 다른 글
[OpenInfoFileWindow] 로컬영역(Application.persistentDataPath) Json 파일 관리 도구 (0) | 2024.10.03 |
---|---|
Coroutine Manager (0) | 2024.03.25 |
Random Seed Generator (0) | 2024.03.24 |
MoveToFileEditor (0) | 2024.03.21 |
PlayerPrefs Viewer 수정 (+float type) (0) | 2024.03.19 |