Json格式的语言包:
[
{
"id": "TXT_NAME",
"Chinese": "名字",
"English": "Name"
},
{
"id": "IMG_GEM",
"Chinese": "Net://https://www.nvsay.com/uploads/allimg/161111/177-1611111436450-L.jpg",
"English": "Net://https://img.mp.sohu.com/upload/20170621/23117ec121394e2584f0dcc617fc0f75_th.png"
},
{
"id": "IMG_GBT",
"Chinese": "Res://Imgs/001",
"English": "Res://Imgs/003"
},
{
"id": "IMG_HHL",
"Chinese": "Imgs/002",
"English": "Imgs/004"
},
{
"id": "IMG_TT",
"Chinese": "AB://AssetBundles/imgs|001",
"English": "AB://AssetBundles/imgs|002"
}
]
需要进行国际化的UI脚本基类 :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class UILocalization<T> : MonoBehaviour where T : Component
{
[SerializeField]
protected T m_Target;
[SerializeField]
protected string m_Key;
// 替换参数
protected object[] m_Args = null;
// 设置键
public virtual void SetKey(string key,params object[] args)
{
if (key != m_Key)
{
m_Key = key;
m_Args = args;
OnChange();
}
}
public void OnChange()
{
if (!string.IsNullOrEmpty(m_Key) && m_Target != null)
{
RefreshShow();
}
m_Args = null;
}
// 刷新显示
protected abstract void RefreshShow();
protected virtual void Start()
{
LocalizationManager.Instance.Register(OnChange);
OnChange();
}
// 获取本地化数据
protected string GetLocalizationData()
{
string data = LocalizationManager.Instance.GetLocalizationData(m_Key);
if (m_Args.IsNotNull() && m_Args.Length > 0)
{
return string.Format(data, m_Args);
}
return data;
}
// 获取组件
protected virtual void OnValidate()
{
if (m_Target == null)
m_Target = GetComponent<T>();
}
protected virtual void OnDestroy()
{
LocalizationManager.Instance.Unregister(OnChange);
}
}
文本脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TextLocalization : UILocalization<Text>
{
protected override void RefreshShow()
{
m_Target.text = GetLocalizationData();
}
}
图片脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ImageLocalization : UILocalization<Image>
{
public enum SrcMode
{
// 自动通过配置表中的url识别
Auto = 0,
// Resources方式加载
Resources,
// AB包加载
AssetBundle,
// 网络加载
Net,
}
[SerializeField]
protected SrcMode m_SrcMode = SrcMode.Auto;
protected override void RefreshShow()
{
string url = GetLocalizationData();
switch (m_SrcMode)
{
case SrcMode.Auto:
LoadAuto(url, m_Target);
break;
case SrcMode.Resources:
StartCoroutine(LoadRes(url, m_Target));
break;
case SrcMode.AssetBundle:
StartCoroutine(LoadAB(url, m_Target));
break;
case SrcMode.Net:
StartCoroutine(LoadNet(url, m_Target));
break;
}
}
private void LoadAuto(string url, Image target)
{
if (url.StartsWith("Res://"))
{
string targetURL = url.RemovePrefixString("Res://");
StartCoroutine(LoadRes(targetURL, target));
}
else if (url.StartsWith("AB://"))
{
string targetURL = url.RemovePrefixString("AB://");
StartCoroutine(LoadAB(targetURL, target));
}
else if (url.StartsWith("Net://"))
{
string targetURL = url.RemovePrefixString("Net://");
StartCoroutine(LoadNet(targetURL, target));
}
}
private IEnumerator LoadNet(string url, Image target)
{
WWW loader = new WWW(url);
yield return loader;
Texture2D texture = loader.texture;
if (texture != null)
{
Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
target.sprite = sprite;
}
}
private IEnumerator LoadAB(string url, Image target)
{
//TODO AB
string[] temps = url.Split('|');
string path = temps[0];
string name = temps[1];
AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(Application.dataPath + "/" + path);
yield return request;
AssetBundleRequest assetReq = request.assetBundle.LoadAssetAsync<Sprite>(name);
yield return assetReq;
Sprite sprite = assetReq.asset as Sprite;
target.sprite = sprite;
AssetBundle.UnloadAllAssetBundles(false);
}
private IEnumerator LoadRes(string url, Image target)
{
ResourceRequest request = Resources.LoadAsync<Sprite>(url);
yield return request;
Sprite sprite = request.asset as Sprite;
//Sprite sprite = Resources.Load<Sprite>(url);
target.sprite = sprite;
}
}
语言国际化管理器:
using System;
using System.Collections.Generic;
using LitJson;
using System.IO;
public class LocalizationManager
{
#region 单例
private static LocalizationManager m_Instance = null;
public static LocalizationManager Instance
{
get
{
if (m_Instance == null)
m_Instance = new LocalizationManager();
return m_Instance;
}
}
#endregion
// 当前的语言
private Language m_Language = Language.Chinese;
public Language Language
{
get
{
return m_Language;
}
}
// 语言列表
private List<string> m_LanguageList;
// 配置文件路径
private string m_ConfigPath;
// 语言数据字典
private Dictionary<string, string> m_LanguageCfgTabel;
// 注册的回调
private Action m_Callback;
// 初始化
public void Init(string configPath)
{
m_LanguageList = new List<string>();
m_ConfigPath = configPath;
m_LanguageCfgTabel = new Dictionary<string, string>();
LoadConfig(configPath);
}
// 设置语言
public void SetLanguage(Language language)
{
if (m_Language != language)
{
this.m_Language = language;
LoadConfig(m_ConfigPath);
if (m_Callback != null)
{
m_Callback();
}
}
}
// 记载配置文件
public void LoadConfig(string path)
{
// 加载语言配置表
if (!File.Exists(path))
{
throw new Exception("配置文件不存在,请检查路径是否错误!Path=" + path);
}
m_LanguageCfgTabel.Clear();
string asset;
using (StreamReader sr = new StreamReader(path))
{
asset = sr.ReadToEnd();
}
if (!string.IsNullOrEmpty(asset))
{
JsonData datas = JsonMapper.ToObject(asset);
string dataKey = m_Language.ToString();
string key = "";
string value = "";
foreach (JsonData data in datas)
{
key = data["id"].ToString();
value = data[dataKey].ToString();
AddDataToTabel(key, value);
}
}
}
// 设置本地化语言列表
public void SetLanguageList(params string[] languages)
{
if (languages != null && languages.Length > 0)
{
for (int i = 0; i < languages.Length; i++)
{
m_LanguageList.Add(languages[i]);
}
}
}
// 获取本地化数据
public string GetLocalizationData(string key)
{
string data;
if(!m_LanguageCfgTabel.TryGetValue(key,out data))
{
throw new System.Exception(string.Format("获取数据失败,key:{0}不存在!",key));
}
return data;
}
// 注册更改语言后的回调
public void Register(Action callback)
{
m_Callback += callback;
}
// 取消注册回调
public void Unregister(Action callback)
{
m_Callback -= callback;
}
// 添加语言数据到语言表
private void AddDataToTabel(string key, string data)
{
if (m_LanguageCfgTabel.ContainsKey(key))
{
throw new System.Exception(string.Format("key:{0}已经存在,请检查配置表中的键值重复项!", key));
}
else
{
m_LanguageCfgTabel.Add(key, data);
}
}
}
语言枚举:
/// <summary>
/// 语言类型
/// </summary>
public enum Language
{
Chinese,
English
}
测试,挂载在GameObject上进行初始化:
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
private void Awake()
{
LocalizationManager.Instance.Init(Application.dataPath + "/Configs/localization.json");
}
int index = 0;
public void OnChangeLanguageBtnClick()
{
index++;
LocalizationManager.Instance.SetLanguage((Language)(index % 2));
}
}
挂载在UI物体上的脚本: