, , ,

Unreal 如何支援 iOS 多語系

讓 Unreal 支援 iOS 的 NSLocalizedString

Unreal 如何支援 iOS 多語系
Photo Source Localization - Apple Developer

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

在 Resource 資料夾中新增 Strings File

如上圖所示, 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 中新增對應語系

Xcode Project Info 內的 Localizations

再找到剛才新增的 strings 檔案

找到 Localize 按鈕
這邊詢問你第一個文件的語系是哪一個,會幫你移到特定語系資料夾內
接著同樣的地方會變成這樣,選擇要自動產生的語系
左邊的檔案就會變成這樣子,可以展開編輯各個語系

如何在 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);
        }
	}
}
首先寫一個 function

接著在 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);
        }
    }
}
遍歷檔案並複製到相對位置

大功告成。