基础内容
必要插件安装 缓动曲线和动画基础 ElementFolder,Track与其次级模块,PathNode重构
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
public static partial class LocalizationManager
|
||||
{
|
||||
|
||||
#region Variables: Misc
|
||||
|
||||
#endregion
|
||||
|
||||
public static void InitializeIfNeeded()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
EditorApplication.playModeStateChanged -= OnEditorPlayModeStateChanged;
|
||||
EditorApplication.playModeStateChanged += OnEditorPlayModeStateChanged;
|
||||
#else
|
||||
UnityEditor.EditorApplication.playmodeStateChanged -= OldOnEditorPlayModeStateChanged;
|
||||
UnityEditor.EditorApplication.playmodeStateChanged += OldOnEditorPlayModeStateChanged;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (string.IsNullOrEmpty(mCurrentLanguage) || Sources.Count == 0)
|
||||
{
|
||||
AutoLoadGlobalParamManagers();
|
||||
UpdateSources();
|
||||
SelectStartupLanguage();
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetVersion()
|
||||
{
|
||||
return "2.8.22 f6";
|
||||
}
|
||||
|
||||
public static int GetRequiredWebServiceVersion()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public static string GetWebServiceURL( LanguageSourceData source = null )
|
||||
{
|
||||
if (source != null && !string.IsNullOrEmpty(source.Google_WebServiceURL))
|
||||
return source.Google_WebServiceURL;
|
||||
|
||||
InitializeIfNeeded();
|
||||
for (int i = 0; i < Sources.Count; ++i)
|
||||
if (Sources[i] != null && !string.IsNullOrEmpty(Sources[i].Google_WebServiceURL))
|
||||
return Sources[i].Google_WebServiceURL;
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
static void OnEditorPlayModeStateChanged( PlayModeStateChange stateChange )
|
||||
{
|
||||
if (stateChange != PlayModeStateChange.ExitingPlayMode)
|
||||
return;
|
||||
#else
|
||||
static void OldOnEditorPlayModeStateChanged()
|
||||
{
|
||||
if (UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
return;
|
||||
#endif
|
||||
|
||||
OnLocalizeEvent = null;
|
||||
|
||||
foreach (var source in Sources)
|
||||
{
|
||||
source.LoadAllLanguages(true);
|
||||
}
|
||||
try
|
||||
{
|
||||
var tempPath = Application.temporaryCachePath;
|
||||
|
||||
foreach (var file in Directory.GetFiles(tempPath).Where(f => f.Contains("LangSource_") && f.EndsWith(".loc", StringComparison.Ordinal)))
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd42f89f650a540d9bd641f752368e27
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,348 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
public static partial class LocalizationManager
|
||||
{
|
||||
#region Variables: CurrentLanguage
|
||||
|
||||
public static string CurrentLanguage
|
||||
{
|
||||
get {
|
||||
InitializeIfNeeded();
|
||||
return mCurrentLanguage;
|
||||
}
|
||||
set {
|
||||
InitializeIfNeeded();
|
||||
string SupportedLanguage = GetSupportedLanguage(value);
|
||||
if (!string.IsNullOrEmpty(SupportedLanguage) && mCurrentLanguage != SupportedLanguage)
|
||||
{
|
||||
SetLanguageAndCode(SupportedLanguage, GetLanguageCode(SupportedLanguage));
|
||||
}
|
||||
}
|
||||
}
|
||||
public static string CurrentLanguageCode
|
||||
{
|
||||
get {
|
||||
InitializeIfNeeded();
|
||||
return mLanguageCode; }
|
||||
set {
|
||||
InitializeIfNeeded();
|
||||
if (mLanguageCode != value)
|
||||
{
|
||||
string LanName = GetLanguageFromCode(value);
|
||||
if (!string.IsNullOrEmpty(LanName))
|
||||
SetLanguageAndCode(LanName, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// "English (United States)" (get returns "United States")
|
||||
// when set "Canada", the new language code will be "English (Canada)"
|
||||
public static string CurrentRegion
|
||||
{
|
||||
get {
|
||||
var Lan = CurrentLanguage;
|
||||
int idx = Lan.IndexOfAny("/\\".ToCharArray());
|
||||
if (idx > 0)
|
||||
return Lan.Substring(idx + 1);
|
||||
|
||||
idx = Lan.IndexOfAny("[(".ToCharArray());
|
||||
int idx2 = Lan.LastIndexOfAny("])".ToCharArray());
|
||||
if (idx > 0 && idx != idx2)
|
||||
return Lan.Substring(idx + 1, idx2 - idx - 1);
|
||||
return string.Empty;
|
||||
}
|
||||
set {
|
||||
var Lan = CurrentLanguage;
|
||||
int idx = Lan.IndexOfAny("/\\".ToCharArray());
|
||||
if (idx > 0)
|
||||
{
|
||||
CurrentLanguage = Lan.Substring(idx + 1) + value;
|
||||
return;
|
||||
}
|
||||
|
||||
idx = Lan.IndexOfAny("[(".ToCharArray());
|
||||
int idx2 = Lan.LastIndexOfAny("])".ToCharArray());
|
||||
if (idx > 0 && idx != idx2)
|
||||
Lan = Lan.Substring(idx);
|
||||
|
||||
CurrentLanguage = Lan + "(" + value + ")";
|
||||
}
|
||||
}
|
||||
|
||||
// "en-US" (get returns "US") (when set "CA", the new language code will be "en-CA")
|
||||
public static string CurrentRegionCode
|
||||
{
|
||||
get {
|
||||
var code = CurrentLanguageCode;
|
||||
int idx = code.IndexOfAny(" -_/\\".ToCharArray());
|
||||
return idx < 0 ? string.Empty : code.Substring(idx + 1);
|
||||
}
|
||||
set {
|
||||
var code = CurrentLanguageCode;
|
||||
int idx = code.IndexOfAny(" -_/\\".ToCharArray());
|
||||
if (idx > 0)
|
||||
code = code.Substring(0, idx);
|
||||
|
||||
CurrentLanguageCode = code + "-" + value;
|
||||
}
|
||||
}
|
||||
|
||||
public static CultureInfo CurrentCulture
|
||||
{
|
||||
get
|
||||
{
|
||||
return mCurrentCulture;
|
||||
}
|
||||
}
|
||||
|
||||
static string mCurrentLanguage;
|
||||
static string mLanguageCode;
|
||||
static CultureInfo mCurrentCulture;
|
||||
static bool mChangeCultureInfo;
|
||||
|
||||
public static bool IsRight2Left;
|
||||
public static bool HasJoinedWords; // Some languages (e.g. Chinese, Japanese and Thai) don't add spaces to their words (all characters are placed toguether)
|
||||
|
||||
#endregion
|
||||
|
||||
public static void SetLanguageAndCode(string LanguageName, string LanguageCode, bool RememberLanguage = true, bool Force = false)
|
||||
{
|
||||
if (mCurrentLanguage != LanguageName || mLanguageCode != LanguageCode || Force)
|
||||
{
|
||||
if (RememberLanguage)
|
||||
PersistentStorage.SetSetting_String("I2 Language", LanguageName);
|
||||
mCurrentLanguage = LanguageName;
|
||||
mLanguageCode = LanguageCode;
|
||||
mCurrentCulture = CreateCultureForCode(LanguageCode);
|
||||
if (mChangeCultureInfo)
|
||||
SetCurrentCultureInfo();
|
||||
|
||||
IsRight2Left = IsRTL(mLanguageCode);
|
||||
HasJoinedWords = GoogleLanguages.LanguageCode_HasJoinedWord(mLanguageCode);
|
||||
LocalizeAll(Force);
|
||||
}
|
||||
}
|
||||
|
||||
static CultureInfo CreateCultureForCode(string code)
|
||||
{
|
||||
#if !NETFX_CORE
|
||||
try
|
||||
{
|
||||
return CultureInfo.CreateSpecificCulture(code);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return CultureInfo.InvariantCulture;
|
||||
}
|
||||
#else
|
||||
return CultureInfo.InvariantCulture;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void EnableChangingCultureInfo(bool bEnable)
|
||||
{
|
||||
if (!mChangeCultureInfo && bEnable)
|
||||
SetCurrentCultureInfo();
|
||||
mChangeCultureInfo = bEnable;
|
||||
}
|
||||
|
||||
static void SetCurrentCultureInfo()
|
||||
{
|
||||
#if !NETFX_CORE
|
||||
Thread.CurrentThread.CurrentCulture = mCurrentCulture;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void SelectStartupLanguage()
|
||||
{
|
||||
if (Sources.Count == 0)
|
||||
return;
|
||||
|
||||
// Use the system language if there is a source with that language,
|
||||
// or pick any of the languages provided by the sources
|
||||
|
||||
string SavedLanguage = PersistentStorage.GetSetting_String("I2 Language", string.Empty);
|
||||
string SysLanguage = GetCurrentDeviceLanguage();
|
||||
|
||||
// Try selecting the System Language
|
||||
// But fallback to the first language found if the System Language is not available in any source
|
||||
|
||||
if (!string.IsNullOrEmpty(SavedLanguage) && HasLanguage(SavedLanguage, Initialize: false, SkipDisabled:true))
|
||||
{
|
||||
SetLanguageAndCode(SavedLanguage, GetLanguageCode(SavedLanguage));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Sources [0].IgnoreDeviceLanguage)
|
||||
{
|
||||
// Check if the device language is supported.
|
||||
// Also recognize when not region is set ("English (United State") will be used if sysLanguage is "English")
|
||||
string ValidLanguage = GetSupportedLanguage (SysLanguage, true);
|
||||
if (!string.IsNullOrEmpty (ValidLanguage)) {
|
||||
SetLanguageAndCode (ValidLanguage, GetLanguageCode (ValidLanguage), false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//--[ Use first language that its not disabled ]-----------
|
||||
for (int i = 0, imax = Sources.Count; i < imax; ++i)
|
||||
if (Sources[i].mLanguages.Count > 0)
|
||||
{
|
||||
for (int j = 0; j < Sources[i].mLanguages.Count; ++j)
|
||||
if (Sources[i].mLanguages[j].IsEnabled())
|
||||
{
|
||||
SetLanguageAndCode(Sources[i].mLanguages[j].Name, Sources[i].mLanguages[j].Code, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static bool HasLanguage( string Language, bool AllowDiscartingRegion = true, bool Initialize=true, bool SkipDisabled=true )
|
||||
{
|
||||
if (Initialize)
|
||||
InitializeIfNeeded();
|
||||
|
||||
// First look for an exact match
|
||||
for (int i=0, imax=Sources.Count; i<imax; ++i)
|
||||
if (Sources[i].GetLanguageIndex(Language, false, SkipDisabled) >=0)
|
||||
return true;
|
||||
|
||||
// Then allow matching "English (Canada)" to "english"
|
||||
if (AllowDiscartingRegion)
|
||||
{
|
||||
for (int i=0, imax=Sources.Count; i<imax; ++i)
|
||||
if (Sources[i].GetLanguageIndex(Language, true, SkipDisabled) >=0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns the provided language or a similar one without the Region
|
||||
//(e.g. "English (Canada)" could be mapped to "english" or "English (United States)" if "English (Canada)" is not found
|
||||
public static string GetSupportedLanguage( string Language, bool ignoreDisabled=false )
|
||||
{
|
||||
// First try finding the language that matches one of the official languages
|
||||
string code = GoogleLanguages.GetLanguageCode(Language);
|
||||
if (!string.IsNullOrEmpty(code))
|
||||
{
|
||||
// First try finding if the exact language code is in one source
|
||||
for (int i = 0, imax = Sources.Count; i < imax; ++i)
|
||||
{
|
||||
int Idx = Sources[i].GetLanguageIndexFromCode(code, true, ignoreDisabled);
|
||||
if (Idx >= 0)
|
||||
return Sources[i].mLanguages[Idx].Name;
|
||||
}
|
||||
|
||||
// If not, try checking without the region
|
||||
for (int i = 0, imax = Sources.Count; i < imax; ++i)
|
||||
{
|
||||
int Idx = Sources[i].GetLanguageIndexFromCode(code, false, ignoreDisabled);
|
||||
if (Idx >= 0)
|
||||
return Sources[i].mLanguages[Idx].Name;
|
||||
}
|
||||
}
|
||||
|
||||
// If not found, then try finding an exact match for the name
|
||||
for (int i=0, imax=Sources.Count; i<imax; ++i)
|
||||
{
|
||||
int Idx = Sources[i].GetLanguageIndex(Language, false, ignoreDisabled);
|
||||
if (Idx>=0)
|
||||
return Sources[i].mLanguages[Idx].Name;
|
||||
}
|
||||
|
||||
// Then allow matching "English (Canada)" to "english"
|
||||
for (int i=0, imax=Sources.Count; i<imax; ++i)
|
||||
{
|
||||
int Idx = Sources[i].GetLanguageIndex(Language, true, ignoreDisabled);
|
||||
if (Idx>=0)
|
||||
return Sources[i].mLanguages[Idx].Name;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public static string GetLanguageCode( string Language )
|
||||
{
|
||||
if (Sources.Count==0)
|
||||
UpdateSources();
|
||||
for (int i=0, imax=Sources.Count; i<imax; ++i)
|
||||
{
|
||||
int Idx = Sources[i].GetLanguageIndex(Language);
|
||||
if (Idx>=0)
|
||||
return Sources[i].mLanguages[Idx].Code;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public static string GetLanguageFromCode( string Code, bool exactMatch=true )
|
||||
{
|
||||
if (Sources.Count==0)
|
||||
UpdateSources();
|
||||
for (int i=0, imax=Sources.Count; i<imax; ++i)
|
||||
{
|
||||
int Idx = Sources[i].GetLanguageIndexFromCode(Code, exactMatch);
|
||||
if (Idx>=0)
|
||||
return Sources[i].mLanguages[Idx].Name;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
public static List<string> GetAllLanguages ( bool SkipDisabled = true )
|
||||
{
|
||||
if (Sources.Count==0)
|
||||
UpdateSources();
|
||||
List<string> Languages = new List<string> ();
|
||||
for (int i=0, imax=Sources.Count; i<imax; ++i)
|
||||
{
|
||||
Languages.AddRange(Sources[i].GetLanguages(SkipDisabled).Where(x=>!Languages.Contains(x)));
|
||||
}
|
||||
return Languages;
|
||||
}
|
||||
|
||||
public static List<string> GetAllLanguagesCode(bool allowRegions=true, bool SkipDisabled = true)
|
||||
{
|
||||
List<string> Languages = new List<string>();
|
||||
for (int i = 0, imax = Sources.Count; i < imax; ++i)
|
||||
{
|
||||
Languages.AddRange(Sources[i].GetLanguagesCode(allowRegions, SkipDisabled).Where(x => !Languages.Contains(x)));
|
||||
}
|
||||
return Languages;
|
||||
}
|
||||
|
||||
public static bool IsLanguageEnabled(string Language)
|
||||
{
|
||||
for (int i = 0, imax = Sources.Count; i < imax; ++i)
|
||||
if (!Sources[i].IsLanguageEnabled(Language))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void LoadCurrentLanguage()
|
||||
{
|
||||
for (int i = 0; i < Sources.Count; ++i)
|
||||
{
|
||||
var iCurrentLang = Sources[i].GetLanguageIndex(mCurrentLanguage, true, false);
|
||||
Sources[i].LoadLanguage(iCurrentLang, true, true, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This function should only be called from within the Localize Inspector to temporaly preview that Language
|
||||
public static void PreviewLanguage(string NewLanguage)
|
||||
{
|
||||
mCurrentLanguage = NewLanguage;
|
||||
mLanguageCode = GetLanguageCode(mCurrentLanguage);
|
||||
IsRight2Left = IsRTL(mLanguageCode);
|
||||
HasJoinedWords = GoogleLanguages.LanguageCode_HasJoinedWord(mLanguageCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d629295da7add24e9465e25cd212bf5
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,195 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
public static partial class LocalizationManager
|
||||
{
|
||||
#region Variables: Misc
|
||||
|
||||
public static List<ILocalizationParamsManager> ParamManagers = new List<ILocalizationParamsManager>();
|
||||
|
||||
|
||||
// returns true if this replaces the normal ApplyLocalizationParams
|
||||
// returns false if after running this function the manager should also run the default ApplyLocalizationParams to replace parameters
|
||||
public delegate bool FnCustomApplyLocalizationParams(ref string translation, _GetParam getParam, bool allowLocalizedParameters);
|
||||
public static FnCustomApplyLocalizationParams CustomApplyLocalizationParams;
|
||||
#endregion
|
||||
|
||||
#region Parameters
|
||||
|
||||
public delegate object _GetParam(string param);
|
||||
|
||||
public static void AutoLoadGlobalParamManagers()
|
||||
{
|
||||
foreach (var manager in Object.FindObjectsOfType<LocalizationParamsManager>())
|
||||
{
|
||||
if (manager._IsGlobalManager && !ParamManagers.Contains(manager))
|
||||
{
|
||||
Debug.Log(manager);
|
||||
ParamManagers.Add(manager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ApplyLocalizationParams(ref string translation, bool allowLocalizedParameters = true)
|
||||
{
|
||||
ApplyLocalizationParams(ref translation, p => GetLocalizationParam(p, null), allowLocalizedParameters);
|
||||
}
|
||||
|
||||
|
||||
public static void ApplyLocalizationParams(ref string translation, GameObject root, bool allowLocalizedParameters = true)
|
||||
{
|
||||
ApplyLocalizationParams(ref translation, p => GetLocalizationParam(p, root), allowLocalizedParameters);
|
||||
}
|
||||
|
||||
public static void ApplyLocalizationParams(ref string translation, Dictionary<string, object> parameters, bool allowLocalizedParameters = true)
|
||||
{
|
||||
ApplyLocalizationParams(ref translation, p => {
|
||||
object o = null;
|
||||
if (parameters.TryGetValue(p, out o))
|
||||
return o;
|
||||
return null;
|
||||
}, allowLocalizedParameters);
|
||||
}
|
||||
|
||||
|
||||
public static void ApplyLocalizationParams(ref string translation, _GetParam getParam, bool allowLocalizedParameters=true)
|
||||
{
|
||||
if (translation == null)
|
||||
return;
|
||||
|
||||
bool skip_processing = CustomApplyLocalizationParams!=null && CustomApplyLocalizationParams.Invoke(ref translation, getParam, allowLocalizedParameters);
|
||||
if (skip_processing) return;
|
||||
|
||||
string pluralType=null;
|
||||
int idx0 = 0;
|
||||
int idx1 = translation.Length;
|
||||
|
||||
int index = 0;
|
||||
while (index>=0 && index<translation.Length)
|
||||
{
|
||||
int iParamStart = translation.IndexOf("{[", index, StringComparison.Ordinal);
|
||||
if (iParamStart < 0) break;
|
||||
|
||||
int iParamEnd = translation.IndexOf("]}", iParamStart, StringComparison.Ordinal);
|
||||
if (iParamEnd < 0) break;
|
||||
|
||||
// there is a sub param, so, skip this one: "this {[helo{[hi]} end"
|
||||
int isubParam = translation.IndexOf("{[", iParamStart+1, StringComparison.Ordinal);
|
||||
if (isubParam>0 && isubParam<iParamEnd)
|
||||
{
|
||||
index = isubParam;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check that some plural parameters can have the form: {[#name]}
|
||||
var offset = translation[iParamStart + 2] == '#' ? 3 : 2;
|
||||
var param = translation.Substring(iParamStart + offset, iParamEnd - iParamStart - offset);
|
||||
var result = (string)getParam(param);
|
||||
if (result != null)
|
||||
{
|
||||
if (allowLocalizedParameters)
|
||||
{
|
||||
// check if Param is Localized
|
||||
LanguageSourceData source;
|
||||
var termData = GetTermData(result, out source);
|
||||
if (termData != null)
|
||||
{
|
||||
int idx = source.GetLanguageIndex(CurrentLanguage);
|
||||
if (idx >= 0)
|
||||
{
|
||||
result = termData.GetTranslation(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var paramTag = translation.Substring(iParamStart, iParamEnd - iParamStart + 2);
|
||||
translation = translation.Replace(paramTag, result);
|
||||
|
||||
int amount = 0;
|
||||
if (int.TryParse(result, out amount))
|
||||
{
|
||||
pluralType = GoogleLanguages.GetPluralType(CurrentLanguageCode, amount).ToString();
|
||||
}
|
||||
|
||||
index = iParamStart + result.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = iParamEnd + 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (pluralType != null)
|
||||
{
|
||||
var tag = "[i2p_" + pluralType + "]";
|
||||
idx0 = translation.IndexOf(tag, StringComparison.OrdinalIgnoreCase);
|
||||
if (idx0 < 0) idx0 = 0;
|
||||
else idx0 += tag.Length;
|
||||
|
||||
idx1 = translation.IndexOf("[i2p_", idx0 + 1, StringComparison.OrdinalIgnoreCase);
|
||||
if (idx1 < 0) idx1 = translation.Length;
|
||||
|
||||
translation = translation.Substring(idx0, idx1 - idx0);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string GetLocalizationParam(string ParamName, GameObject root)
|
||||
{
|
||||
string result = null;
|
||||
if (root)
|
||||
{
|
||||
var components = root.GetComponents<MonoBehaviour>();
|
||||
for (int i = 0, imax = components.Length; i < imax; ++i)
|
||||
{
|
||||
var manager = components[i] as ILocalizationParamsManager;
|
||||
if (manager != null && components[i].enabled)
|
||||
{
|
||||
result = manager.GetParameterValue(ParamName);
|
||||
if (result != null)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0, imax = ParamManagers.Count; i < imax; ++i)
|
||||
{
|
||||
result = ParamManagers[i].GetParameterValue(ParamName);
|
||||
if (result != null)
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Plural
|
||||
|
||||
private static string GetPluralType( MatchCollection matches, string langCode, _GetParam getParam)
|
||||
{
|
||||
for (int i = 0, nMatches = matches.Count; i < nMatches; ++i)
|
||||
{
|
||||
var match = matches[i];
|
||||
var param = match.Groups[match.Groups.Count - 1].Value;
|
||||
var result = (string)getParam(param);
|
||||
if (result == null)
|
||||
continue;
|
||||
|
||||
int amount = 0;
|
||||
if (!int.TryParse (result, out amount))
|
||||
continue;
|
||||
|
||||
var pluralType = GoogleLanguages.GetPluralType(langCode, amount);
|
||||
return pluralType.ToString ();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9bdcae51172bbb8458cf8c42f889c2a0
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
public static partial class LocalizationManager
|
||||
{
|
||||
static string[] LanguagesRTL = {"ar-DZ", "ar","ar-BH","ar-EG","ar-IQ","ar-JO","ar-KW","ar-LB","ar-LY","ar-MA","ar-OM","ar-QA","ar-SA","ar-SY","ar-TN","ar-AE","ar-YE",
|
||||
"fa", "he","ur","ji"};
|
||||
|
||||
public static string ApplyRTLfix(string line) { return ApplyRTLfix(line, 0, true); }
|
||||
public static string ApplyRTLfix(string line, int maxCharacters, bool ignoreNumbers)
|
||||
{
|
||||
if (string.IsNullOrEmpty(line))
|
||||
return line;
|
||||
|
||||
// Fix !, ? and . signs not set correctly
|
||||
char firstC = line[0];
|
||||
if (firstC == '!' || firstC == '.' || firstC == '?')
|
||||
line = line.Substring(1) + firstC;
|
||||
|
||||
int tagStart = -1, tagEnd = 0;
|
||||
|
||||
// Find all Tags (and Numbers if ignoreNumbers is true)
|
||||
int tagBase = 0xFFFB;
|
||||
tagEnd = 0;
|
||||
var tags = new List<string>();
|
||||
while (I2Utils.FindNextTag(line, tagEnd, out tagStart, out tagEnd))
|
||||
{
|
||||
char tag = (char)(tagBase - tags.Count);
|
||||
tags.Add(line.Substring(tagStart, tagEnd - tagStart + 1));
|
||||
|
||||
line = line.Substring(0, tagStart) + tag + line.Substring(tagEnd + 1);
|
||||
tagEnd = tagStart + 1;
|
||||
}
|
||||
|
||||
// Split into lines and fix each line
|
||||
line = line.Replace("\r\n", "\n");
|
||||
line = I2Utils.SplitLine(line, maxCharacters);
|
||||
line = RTLFixer.Fix(line, true, !ignoreNumbers);
|
||||
|
||||
|
||||
// Restore all tags
|
||||
|
||||
for (int i = 0; i < tags.Count; i++)
|
||||
{
|
||||
string old_tag = ((char)(tagBase - i)).ToString();
|
||||
string new_tag = I2Utils.ReverseText(tags[i]);
|
||||
|
||||
line = line.Replace(old_tag, new_tag);
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
public static string FixRTL_IfNeeded(string text, int maxCharacters = 0, bool ignoreNumber=false)
|
||||
{
|
||||
if (IsRight2Left)
|
||||
return ApplyRTLfix(text, maxCharacters, ignoreNumber);
|
||||
return text;
|
||||
}
|
||||
|
||||
public static bool IsRTL(string Code)
|
||||
{
|
||||
return Array.IndexOf(LanguagesRTL, Code)>=0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d33b5082085040d44ab79b83d25bffee
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
public static partial class LocalizationManager
|
||||
{
|
||||
|
||||
#region Variables: Misc
|
||||
|
||||
public static List<LanguageSourceData> Sources = new List<LanguageSourceData>();
|
||||
public static string[] GlobalSources = { "I2Languages" };
|
||||
|
||||
#endregion
|
||||
|
||||
#region Sources
|
||||
|
||||
public static bool UpdateSources()
|
||||
{
|
||||
UnregisterDeletededSources();
|
||||
RegisterSourceInResources();
|
||||
RegisterSceneSources();
|
||||
return Sources.Count>0;
|
||||
}
|
||||
|
||||
static void UnregisterDeletededSources()
|
||||
{
|
||||
// Delete sources that were part of another scene and not longer available
|
||||
for (int i=Sources.Count-1; i>=0; --i)
|
||||
if (Sources[i] == null)
|
||||
RemoveSource( Sources[i] );
|
||||
}
|
||||
|
||||
static void RegisterSceneSources()
|
||||
{
|
||||
LanguageSource[] sceneSources = (LanguageSource[])Resources.FindObjectsOfTypeAll( typeof(LanguageSource) );
|
||||
foreach (LanguageSource source in sceneSources)
|
||||
if (!Sources.Contains(source.mSource))
|
||||
{
|
||||
if (source.mSource.owner == null)
|
||||
source.mSource.owner = source;
|
||||
AddSource( source.mSource );
|
||||
}
|
||||
}
|
||||
|
||||
static void RegisterSourceInResources()
|
||||
{
|
||||
// Find the Source that its on the Resources Folder
|
||||
foreach (string SourceName in GlobalSources)
|
||||
{
|
||||
LanguageSourceAsset sourceAsset = ResourceManager.pInstance.GetAsset<LanguageSourceAsset>(SourceName);
|
||||
|
||||
if (sourceAsset && !Sources.Contains(sourceAsset.mSource))
|
||||
{
|
||||
if (!sourceAsset.mSource.mIsGlobalSource)
|
||||
sourceAsset.mSource.mIsGlobalSource = true;
|
||||
sourceAsset.mSource.owner = sourceAsset;
|
||||
AddSource(sourceAsset.mSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Func<LanguageSourceData, bool> Callback_AllowSyncFromGoogle = null;
|
||||
static bool AllowSyncFromGoogle(LanguageSourceData Source)
|
||||
{
|
||||
if (Callback_AllowSyncFromGoogle == null)
|
||||
return true;
|
||||
return Callback_AllowSyncFromGoogle.Invoke(Source);
|
||||
}
|
||||
|
||||
internal static void AddSource ( LanguageSourceData Source )
|
||||
{
|
||||
if (Sources.Contains (Source))
|
||||
return;
|
||||
|
||||
Sources.Add( Source );
|
||||
|
||||
if (Source.HasGoogleSpreadsheet() && Source.GoogleUpdateFrequency != LanguageSourceData.eGoogleUpdateFrequency.Never && AllowSyncFromGoogle(Source))
|
||||
{
|
||||
#if !UNITY_EDITOR
|
||||
Source.Import_Google_FromCache();
|
||||
bool justCheck = false;
|
||||
#else
|
||||
bool justCheck=true;
|
||||
#endif
|
||||
if (Source.GoogleUpdateDelay > 0)
|
||||
CoroutineManager.Start( Delayed_Import_Google(Source, Source.GoogleUpdateDelay, justCheck) );
|
||||
else
|
||||
Source.Import_Google(false, justCheck);
|
||||
}
|
||||
|
||||
//if (force)
|
||||
{
|
||||
for (int i = 0; i < Source.mLanguages.Count; ++i)
|
||||
Source.mLanguages[i].SetLoaded(true);
|
||||
}
|
||||
|
||||
if (Source.mDictionary.Count==0)
|
||||
Source.UpdateDictionary(true);
|
||||
}
|
||||
|
||||
static IEnumerator Delayed_Import_Google ( LanguageSourceData source, float delay, bool justCheck )
|
||||
{
|
||||
yield return new WaitForSeconds( delay );
|
||||
if (source != null) // handle cases where the source is already deleted
|
||||
{
|
||||
source.Import_Google(false, justCheck);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void RemoveSource (LanguageSourceData Source )
|
||||
{
|
||||
//Debug.Log ("RemoveSource " + Source+" " + Source.GetInstanceID());
|
||||
Sources.Remove( Source );
|
||||
}
|
||||
|
||||
public static bool IsGlobalSource( string SourceName )
|
||||
{
|
||||
return Array.IndexOf(GlobalSources, SourceName)>=0;
|
||||
}
|
||||
|
||||
public static LanguageSourceData GetSourceContaining( string term, bool fallbackToFirst = true )
|
||||
{
|
||||
if (!string.IsNullOrEmpty(term))
|
||||
{
|
||||
for (int i=0, imax=Sources.Count; i<imax; ++i)
|
||||
{
|
||||
if (Sources[i].GetTermData(term) != null)
|
||||
return Sources[i];
|
||||
}
|
||||
}
|
||||
|
||||
return fallbackToFirst && Sources.Count>0 ? Sources[0] : null;
|
||||
}
|
||||
|
||||
public static Object FindAsset (string value)
|
||||
{
|
||||
for (int i=0, imax=Sources.Count; i<imax; ++i)
|
||||
{
|
||||
Object Obj = Sources[i].FindAsset(value);
|
||||
if (Obj)
|
||||
return Obj;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void ApplyDownloadedDataFromGoogle()
|
||||
{
|
||||
for (int i = 0, imax = Sources.Count; i < imax; ++i)
|
||||
{
|
||||
Sources[i].ApplyDownloadedDataFromGoogle();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc9fa6be47f55724e920863a231f889c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,44 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
public static partial class LocalizationManager
|
||||
{
|
||||
static string mCurrentDeviceLanguage;
|
||||
|
||||
public static string GetCurrentDeviceLanguage( bool force = false )
|
||||
{
|
||||
if (force || string.IsNullOrEmpty(mCurrentDeviceLanguage))
|
||||
DetectDeviceLanguage();
|
||||
|
||||
return mCurrentDeviceLanguage;
|
||||
}
|
||||
|
||||
static void DetectDeviceLanguage()
|
||||
{
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
try {
|
||||
AndroidJavaObject locale = new AndroidJavaClass("java/util/Locale").CallStatic<AndroidJavaObject>("getDefault");
|
||||
mCurrentDeviceLanguage = locale.Call<string>("toString");
|
||||
//https://stackoverflow.com/questions/4212320/get-the-current-language-in-device
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(mCurrentDeviceLanguage))
|
||||
{
|
||||
mCurrentDeviceLanguage = mCurrentDeviceLanguage.Replace('_', '-');
|
||||
mCurrentDeviceLanguage = GoogleLanguages.GetLanguageName(mCurrentDeviceLanguage, true, true);
|
||||
if (!string.IsNullOrEmpty(mCurrentDeviceLanguage))
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
mCurrentDeviceLanguage = Application.systemLanguage.ToString();
|
||||
if (mCurrentDeviceLanguage == "ChineseSimplified") mCurrentDeviceLanguage = "Chinese (Simplified)";
|
||||
if (mCurrentDeviceLanguage == "ChineseTraditional") mCurrentDeviceLanguage = "Chinese (Traditional)";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd54e24a8c653f341a9540011ba06f01
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
public static partial class LocalizationManager
|
||||
{
|
||||
|
||||
#region Variables: Misc
|
||||
|
||||
public static List<ILocalizeTargetDescriptor> mLocalizeTargets = new List<ILocalizeTargetDescriptor>();
|
||||
|
||||
#endregion
|
||||
|
||||
public static void RegisterTarget( ILocalizeTargetDescriptor desc )
|
||||
{
|
||||
if (mLocalizeTargets.FindIndex(x => x.Name == desc.Name) != -1)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < mLocalizeTargets.Count; ++i)
|
||||
{
|
||||
if (mLocalizeTargets[i].Priority > desc.Priority)
|
||||
{
|
||||
mLocalizeTargets.Insert(i, desc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
mLocalizeTargets.Add(desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84ead5dc664fd394490f4874012ed099
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,225 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
public static partial class LocalizationManager
|
||||
{
|
||||
|
||||
#region Variables: Misc
|
||||
|
||||
public delegate void OnLocalizeCallback();
|
||||
public static event OnLocalizeCallback OnLocalizeEvent;
|
||||
|
||||
static bool mLocalizeIsScheduled;
|
||||
static bool mLocalizeIsScheduledWithForcedValue;
|
||||
|
||||
public static bool HighlightLocalizedTargets = false;
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
public static string GetTranslation(string Term, bool FixForRTL = true, int maxLineLengthForRTL = 0, bool ignoreRTLnumbers = true, bool applyParameters = false, GameObject localParametersRoot = null, string overrideLanguage = null, bool allowLocalizedParameters=true)
|
||||
{
|
||||
string Translation = null;
|
||||
TryGetTranslation(Term, out Translation, FixForRTL, maxLineLengthForRTL, ignoreRTLnumbers, applyParameters, localParametersRoot, overrideLanguage, allowLocalizedParameters);
|
||||
|
||||
return Translation;
|
||||
}
|
||||
public static string GetTermTranslation(string Term, bool FixForRTL = true, int maxLineLengthForRTL = 0, bool ignoreRTLnumbers = true, bool applyParameters = false, GameObject localParametersRoot = null, string overrideLanguage = null, bool allowLocalizedParameters=true)
|
||||
{
|
||||
return GetTranslation(Term, FixForRTL, maxLineLengthForRTL, ignoreRTLnumbers, applyParameters, localParametersRoot, overrideLanguage, allowLocalizedParameters);
|
||||
}
|
||||
|
||||
|
||||
public static bool TryGetTranslation(string Term, out string Translation, bool FixForRTL = true, int maxLineLengthForRTL = 0, bool ignoreRTLnumbers = true, bool applyParameters = false, GameObject localParametersRoot = null, string overrideLanguage = null, bool allowLocalizedParameters=true)
|
||||
{
|
||||
Translation = null;
|
||||
if (string.IsNullOrEmpty(Term))
|
||||
return false;
|
||||
|
||||
InitializeIfNeeded();
|
||||
|
||||
for (int i = 0, imax = Sources.Count; i < imax; ++i)
|
||||
{
|
||||
if (Sources[i].TryGetTranslation(Term, out Translation, overrideLanguage))
|
||||
{
|
||||
if (applyParameters)
|
||||
ApplyLocalizationParams(ref Translation, localParametersRoot, allowLocalizedParameters);
|
||||
|
||||
if (IsRight2Left && FixForRTL)
|
||||
Translation = ApplyRTLfix(Translation, maxLineLengthForRTL, ignoreRTLnumbers);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static T GetTranslatedObject<T>( string AssetName, Localize optionalLocComp=null) where T : Object
|
||||
{
|
||||
if (optionalLocComp != null)
|
||||
{
|
||||
return optionalLocComp.FindTranslatedObject<T>(AssetName);
|
||||
}
|
||||
|
||||
T obj = FindAsset(AssetName) as T;
|
||||
if (obj)
|
||||
return obj;
|
||||
|
||||
obj = ResourceManager.pInstance.GetAsset<T>(AssetName);
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static T GetTranslatedObjectByTermName<T>( string Term, Localize optionalLocComp=null) where T : Object
|
||||
{
|
||||
string translation = GetTranslation(Term, FixForRTL: false);
|
||||
return GetTranslatedObject<T>(translation);
|
||||
}
|
||||
|
||||
|
||||
public static string GetAppName(string languageCode)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(languageCode))
|
||||
{
|
||||
for (int i = 0; i < Sources.Count; ++i)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Sources[i].mTerm_AppName))
|
||||
continue;
|
||||
|
||||
int langIdx = Sources[i].GetLanguageIndexFromCode(languageCode, false);
|
||||
if (langIdx < 0)
|
||||
continue;
|
||||
|
||||
var termData = Sources[i].GetTermData(Sources[i].mTerm_AppName);
|
||||
if (termData == null)
|
||||
continue;
|
||||
|
||||
var appName = termData.GetTranslation(langIdx);
|
||||
if (!string.IsNullOrEmpty(appName))
|
||||
return appName;
|
||||
}
|
||||
}
|
||||
|
||||
return Application.productName;
|
||||
}
|
||||
|
||||
public static void LocalizeAll(bool Force = false)
|
||||
{
|
||||
LoadCurrentLanguage();
|
||||
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
DoLocalizeAll(Force);
|
||||
return;
|
||||
}
|
||||
mLocalizeIsScheduledWithForcedValue |= Force;
|
||||
if (mLocalizeIsScheduled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CoroutineManager.Start(Coroutine_LocalizeAll());
|
||||
}
|
||||
|
||||
static IEnumerator Coroutine_LocalizeAll()
|
||||
{
|
||||
mLocalizeIsScheduled = true;
|
||||
yield return null;
|
||||
mLocalizeIsScheduled = false;
|
||||
var force = mLocalizeIsScheduledWithForcedValue;
|
||||
mLocalizeIsScheduledWithForcedValue = false;
|
||||
DoLocalizeAll(force);
|
||||
}
|
||||
|
||||
static void DoLocalizeAll(bool Force = false)
|
||||
{
|
||||
Localize[] Locals = (Localize[])Resources.FindObjectsOfTypeAll( typeof(Localize) );
|
||||
for (int i=0, imax=Locals.Length; i<imax; ++i)
|
||||
{
|
||||
Localize local = Locals[i];
|
||||
//if (ObjectExistInScene (local.gameObject))
|
||||
local.OnLocalize(Force);
|
||||
}
|
||||
if (OnLocalizeEvent != null)
|
||||
OnLocalizeEvent ();
|
||||
//ResourceManager.pInstance.CleanResourceCache();
|
||||
#if UNITY_EDITOR
|
||||
RepaintInspectors();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
static void RepaintInspectors()
|
||||
{
|
||||
var assemblyEditor = Assembly.GetAssembly(typeof(Editor));
|
||||
var typeInspectorWindow = assemblyEditor.GetType("UnityEditor.InspectorWindow");
|
||||
if (typeInspectorWindow != null)
|
||||
{
|
||||
typeInspectorWindow.GetMethod("RepaintAllInspectors", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
public static List<string> GetCategories ()
|
||||
{
|
||||
List<string> Categories = new List<string> ();
|
||||
for (int i=0, imax=Sources.Count; i<imax; ++i)
|
||||
Sources[i].GetCategories(false, Categories);
|
||||
return Categories;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static List<string> GetTermsList ( string Category = null )
|
||||
{
|
||||
if (Sources.Count==0)
|
||||
UpdateSources();
|
||||
|
||||
if (Sources.Count==1)
|
||||
return Sources[0].GetTermsList(Category);
|
||||
|
||||
HashSet<string> Terms = new HashSet<string> ();
|
||||
for (int i=0, imax=Sources.Count; i<imax; ++i)
|
||||
Terms.UnionWith( Sources[i].GetTermsList(Category) );
|
||||
return new List<string>(Terms);
|
||||
}
|
||||
|
||||
public static TermData GetTermData( string term )
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
|
||||
TermData data;
|
||||
for (int i=0, imax=Sources.Count; i<imax; ++i)
|
||||
{
|
||||
data = Sources[i].GetTermData(term);
|
||||
if (data!=null)
|
||||
return data;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
public static TermData GetTermData(string term, out LanguageSourceData source)
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
|
||||
TermData data;
|
||||
for (int i = 0, imax = Sources.Count; i < imax; ++i)
|
||||
{
|
||||
data = Sources[i].GetTermData(term);
|
||||
if (data != null)
|
||||
{
|
||||
source = Sources[i];
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
source = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 493a31b7ceba6734491324975bbb928c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user