1. 程式人生 > >Unity外掛I2Localization原始碼分析

Unity外掛I2Localization原始碼分析

本地化的基礎流程

  1. 獲得本地化字串LanguageSource.GetTranslationLocalizationManager.GetTermTranslation
  2. 如果屬於資源類就LanguageSource.FindAssetLocalizationManager.FindAsset

LocalizationManager

  1. 記錄所有例項
    • 所有LanguageSource,用於訪問到所有本地化資料
    • 所有註冊的ILocalizeTarget,用於處理對不同型別指令碼的具體本地化邏輯
    • 所有註冊的ILocalizationParamsManager,用於處理{[???]}引數的嵌入邏輯
  2. 提供主要靜態方法
    • 本地化方法如:LocalizeAll,GetTermTranslation,GetAppName,ApplyLocalizationParams
    • 工具方法如:ApplyRTLfix
    • 資源方法如:FindAsset

LanguageSource

翻譯資料的儲存位置

  1. TermData
    • 本地化文字儲存的類
    • 無論什麼型別的資源,都會最終存為字串型別。如果為資源型別,則需要再查詢資源。
      • 如:sprite會存成資源的名字xxx。在使用的時候,再去本地化系統中的Assets裡邊去查詢
  2. LanguageData
    • 語言配置
  3. Assets
    • 儲存當前LanguageSource用到的資源

Localize 和 ILocalizeTarget

ILocalizeTarget為不同型別指令碼的具體漢化邏輯。Localize在初始化的時候會從LocalizationManager獲得當前適用的ILocalizeTarget

層次結構如下

public abstract class ILocalizeTarget
public abstract class LocalizeTarget<T> : ILocalizeTarget where T : Object
public class LocalizeTarget_UnityUI_Text : LocalizeTarget<UnityEngine.UI.Text> {}

public
class LocalizeTarget_UnityUI_Image : LocalizeTarget<UnityEngine.UI.Image> { public override void GetFinalTerms ( Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm ) { // 獲取需要的指令碼 var mTarget = GetTarget(cmp); // 用mainTexture.name作為本地化key primaryTerm = mTarget.mainTexture ? mTarget.mainTexture.name : ""; if (mTarget.sprite!=null && mTarget.sprite.name!=primaryTerm) primaryTerm += "." + mTarget.sprite.name; secondaryTerm = null; } public override void DoLocalize ( Localize cmp, string mainTranslation, string secondaryTranslation ) { var mTarget = GetTarget(cmp); // 對物體進行本地化 Sprite Old = mTarget.sprite; if (Old==null || Old.name!=mainTranslation) mTarget.sprite = cmp.FindTranslatedObject<Sprite>( mainTranslation ); } }

引數的處理

You have {[VALUE1]} points.
通過{[???]}的形式儲存的字串,通過正則查找出來({\[(.*?)\]}
在執行本地化的時候,會查詢全域性的ILocalizationParamsManager。進匹配成功的引數進行替換。

複數的處理

You have {[VALUE1]} points.[i2p_Zero]You have no points.[i2p_One]You have 1 point.
如果一個翻譯串裡邊出現{[VALUE]}一類的引數,就可以設定複數形式。內部儲存如上。

if (pluralType != null) 
{
    var tag = "[i2p_" + pluralType + "]";
    idx0 = translation.IndexOf (tag, System.StringComparison.OrdinalIgnoreCase);
    if (idx0 < 0) idx0 = 0;
             else idx0 += tag.Length;

    idx1 = translation.IndexOf ("[i2p_", idx0+1, System.StringComparison.OrdinalIgnoreCase);
    if (idx1 < 0) idx1 = translation.Length;

    translation = translation.Substring(idx0, idx1-idx0);
}

上述程式碼查詢i2p的標籤進行字串裁剪