基础内容

必要插件安装
缓动曲线和动画基础
ElementFolder,Track与其次级模块,PathNode重构
This commit is contained in:
SoulliesOfficial
2025-01-26 21:10:16 -05:00
parent 40f63dd2bd
commit 8d0abec75f
9320 changed files with 2950357 additions and 0 deletions

View File

@@ -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
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: dd42f89f650a540d9bd641f752368e27
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 7d629295da7add24e9465e25cd212bf5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 9bdcae51172bbb8458cf8c42f889c2a0
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: d33b5082085040d44ab79b83d25bffee
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: fc9fa6be47f55724e920863a231f889c
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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)";
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: fd54e24a8c653f341a9540011ba06f01
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 84ead5dc664fd394490f4874012ed099
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 493a31b7ceba6734491324975bbb928c
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: