Unreal 如何支援 iOS 多語系
讓 Unreal 支援 iOS 的 NSLocalizedString

首先在 Xcode 中先新增 iOS 的多語系檔案

如上圖所示, Strings File
是 iOS 多語系的定義文件,在新增時 Strings File
的文件命名決定它的功能:
Localizable
- 應用程式或遊戲內的多語系文檔。InfoPlist
- 應用程式系統層面的多語系文字 e.g., App Name, Runtime Permission 說明文字
Localizable
這一個相對簡單,只要將文字用 key value 的形式定義好,使用 key 來呼叫就好
"Hello" : "哈囉";
NSString* helloText = NSLocalizedString(@"Hello", @"Hello");
InfoPlist
這一個主要是對 InfoPlist 內的一些欄位做多語系的設定,雖然也是 key value 的格式,但 key 有絕對的寫法,無法自行命名
"CFBundleDisplayName" : "測試 APP";
下方可以找到官方的 key 定義
Core Foundation Keys
Describes the keys for a bundle’s Info.plist file.
多種語言設定
iOS 的多語系文件其實就是不同語言各寫一個 strings 文件,然後放到不同的語系資料夾
資料夾名稱命名方式為 {LanguageCode}.lproj
- 繁體中文 -
zh-hant.lproj
- 英文 -
en.lproj
- 日文 -
ja.lproj
- 韓文 -
ko.lproj
也可以利用 Xcode 快速產生,首先先在專案 Project 中的 Localizations 中新增對應語系

再找到剛才新增的 strings 檔案




如何在 Unreal 中使用
如果說整個 Unreal 專案只有自己在使用,可以直接將所有的語系資料夾複製到專案底下的 Build/IOS/Resources/Localizations/
底下,Unreal 在編譯時會自動採用。
倘若是跟我一樣開發的是 Plugins 我的方法是先把資源檔案放到 Plugins/模組/Resources/Localizations 底下

接著我在 Module 的 Build.cs 內寫下以下的 Code 來幫我自動複製到專案的 Build/IOS/Resources/Localizations/
底下
/// <summary>
/// 將指定資料夾中的檔案複製到指定的資料夾中
/// </summary>
/// <param name="sourceDirectory">指定資料夾</param>
/// <param name="destinationDirectory">目的資料夾</param>
private void CopyFileToDirectory(string sourceDirectory, string destinationDirectory)
{
if (Directory.GetDirectories(sourceDirectory).Length > 0)
{
foreach (string file in Directory.GetFiles(sourceDirectory))
{
string fileName = Path.GetFileName(file);
string destFile = Path.Combine(destinationDirectory, fileName);
if (!Directory.Exists(destinationDirectory))
{
Directory.CreateDirectory(destinationDirectory);
}
// 第三個參數代表若已有檔案是否覆蓋。
File.Copy(file, destFile, true);
}
}
}
接著在 Module 建構子當中 iOS 輸出的地方加上
if (Target.Platform == UnrealTargetPlatform.IOS)
{
// 複製 iOS runtime permission strings
string ResourcesPath = Path.GetFullPath(Path.Combine(PluginDirectory, "Resources/Localizations"));
string DestinationPath = Path.GetFullPath(Path.Combine(PluginDirectory, "../../Build/IOS/Resources/Localizations"));
if (Directory.Exists(ResourcesPath))
{
if (!Directory.Exists(DestinationPath))
{
Directory.CreateDirectory(DestinationPath);
}
// 將 ResourcesPath 內的檔案複製到 DestinationPath
this.CopyFileToDirectory(ResourcesPath, DestinationPath);
// 將 ResourcesPath 內的資料夾複製到 DestinationPath
foreach (string dir in Directory.GetDirectories(ResourcesPath))
{
string dirName = Path.GetFileName(dir);
string destDir = Path.Combine(DestinationPath, dirName);
this.CopyFileToDirectory(dir, destDir);
}
}
}
大功告成。