多语言切换
unity实现多语言切换就需要有类似与语言包一样的东西,这里我将语言包整成Txt文本的形式存放,大家也可以转换成其他形式存储。
在脚本中有个Init方法是用于初始化语言包信息的只有调用了Init方法调用程序中的其他方法才有效。
init方法可重复调用。
调用Init方法时需要传递参数Language结构的内容。
Language结构
Language结构中的m_Type为语言类型为必须传递的参数。
Language结构中的语言文本有三种,只需传递一种就可以。
语言文本中形成 Text Key = [Value] 格式为有效的文本格式且文本格式必须在同一行内方为有效.
格式中的Key值只能由《 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ 》组成且Key中不能由空格存在。
格式中的Value值得存在必须写在中括号里面
public struct Language
{
/// <summary>
/// 语言类型
/// </summary>
public LanguageType m_Type;
/// <summary>
/// 语言文本
/// </summary>
public TextAsset m_Txt;
/// <summary>
/// 语言文本
/// </summary>
public byte[] bytes;
/// <summary>
/// 语言文本
/// </summary>
public string text;
}
Demo
下面是写在Chinese.txt中得内容
Text Home_Title_00 = [首页]
Text Home_Title_01 = [登陆]
Text Home_Title_02 = [退出]
下面是写在English.txt中得内容
Text Home_Title_00 = [Home]
Text Home_Title_01 = [Login]
Text Home_Title_02 = [Exit]
在两个文本中写有相同得key组成得语言库就可在实现语言切换
将需要实现语言切换得方法添加进切换语言回调中即可
调用Add方法即可添加语言切换回调。
调用Setting_LanguageType方法即可切换当前语言形式,切换成功会调用已添加回调。
在回调中重新调用GetValueToKey方法即可实现语言切换。
完整代码中的 ValueToKey 由样式
下面为初始化语言的Demo
TextAsset chinese; //中文语言上文中的chinese.txt
TextAsset english; //英文语言上文中的english.txt
private void Awake()
{
//初始化语言包
LanguageManager.GetManager.Init(new Language{
m_Type = LanguageType.Chinese,
m_Txt = chinese,
},
new Language{
m_Type = LanguageType.English,
m_Txt = english,
}
);
}
完整的代码
ValueToKey获取语言得帮助脚本将其挂载在Text或TextMesh上,然后填写Key得值即可配合LanguageManager一起使用。
[AddComponentMenu("UI/TextValue")]
public class ValueToKey : MonoBehaviour
{
[SerializeField]
private string Key;
public string GetKey { get { return Key; } }
/// <summary>
///
/// </summary>
public Text m_Content;
public TextMesh m_Content_3D;
private void Awake()
{
LanguageManager.GetManager.Add(GetValueToKey);
if (m_Content_3D == null)
m_Content_3D = this.transform.GetComponent<TextMesh>();
if (m_Content == null)
m_Content = this.transform.GetComponent<Text>();
GetValueToKey();
}
/// <summary>
/// 设置Key值并更新Value
/// </summary>
/// <param name="varKey"></param>
public void SettingKey(string varKey)
{
Key = varKey;
GetValueToKey();
}
private void OnEnable()
{
if (!string.IsNullOrEmpty(Key))
{
GetValueToKey();
}
}
private void GetValueToKey()
{
string Value = LanguageManager.GetManager.GetValueToKey(Key);
if (m_Content != null)
m_Content.text = Value;
if (m_Content_3D != null)
m_Content_3D.text = Value;
}
}
LanguageManager多语言切换得关键性脚本
/// <summary>
/// 语言文字管理
/// * ===========================================================
/// * 文本的有效格式 Text Key = [Value];
/// * 文本的有效格式中的信息必须在一行中实现才能视为有效格式。
/// * 若Value中有换行的内容可用转义字符\n表示,Value中不可出现\f字符否则会导致该Value的计算错误
/// * Txt文本的编码格式必须为UTF-8的编码格式
/// * key 于 Value 形成键值对的格式
/// * key中不能有空格的出现
/// * key值只能有字母数字和下划线构成
/// * Value的必须在中括号内该写法可让Value值没有其他的局限性
/// * ===========================================================
/// </summary>
public class LanguageManager : MonoBehaviour
{
private static LanguageManager _Manager;
/// <summary>
/// 单例模式可方便调用
/// </summary>
public static LanguageManager GetManager
{
get
{
if (_Manager == null)
{
GameObject Go = new GameObject("LanguageManager");
GameObject.DontDestroyOnLoad(Go);
_Manager = Go.AddComponent<LanguageManager >();
}
return _Manager;
}
}
//切换语言回调
private List<Action> CallBack = new List<Action>();
/// <summary>
/// 语言类型
/// </summary>
public enum LanguageType
{
/// <summary>
/// 中文
/// </summary>
Chinese,
/// <summary>
/// 英文
/// </summary>
English,
/// <summary>
/// 其他语言
/// </summary>
Other
}
//默认语言类型
private LanguageType m_Language = LanguageType.Chinese;
/// <summary>
/// 初始化语言包
/// </summary>
/// <param name="language"></param>
public void Init(params Language[] language)
{
ReadText(language);
}
/// <summary>
/// 获取值
/// </summary>
/// <param name="Key"></param>
/// <returns></returns>
public string GetValueToKey(string Key)
{
if (!Dic_Language.ContainsKey(m_Language))
return Key;
Dictionary<string, string> Temp_Language = new Dictionary<string, string>();
if (!Dic_Language.TryGetValue(m_Language, out Temp_Language))
return Key;
return GetValue(Key, Temp_Language);
}
/// <summary>
/// 添加语言切换回调(方便实现项目中的语言切换功能)
/// </summary>
/// <param name="action"></param>
public void Add(Action action)
{
if (CallBack.Contains(action))
return;
CallBack.Add(action);
}
/// <summary>
/// 切换语言
/// </summary>
public LanguageType Setting_LanguageType
{
set
{
m_Language = value;
for (int i = 0; i < CallBack.Count; i++)
{
var fn = CallBack[i];
if (fn != null)
fn();
}
}
}
/// <summary>
/// 语言字典
/// </summary>
protected Dictionary<LanguageType, Dictionary<string, string>> Dic_Language = new Dictionary<LanguageType, Dictionary<string, string>>();
private void ReadText(Language[] varLanguage)
{
for (int i = 0; i < varLanguage.Length; i++)
{
Language Temp_Language = varLanguage[i];
if (Dic_Language.ContainsKey(Temp_Language.m_Type))
{
Dictionary<string, string> Temp_DIC_Language = Dic_Language[Temp_Language.m_Type];
ReadTextAsset(Temp_Language, Temp_DIC_Language);
}
else
{
Dictionary<string, string> Temp_DIC_Language = new Dictionary<string, string>();
ReadTextAsset(Temp_Language, Temp_DIC_Language);
Dic_Language.Add(Temp_Language.m_Type, Temp_DIC_Language);
}
}
}
/// <summary>
/// 读取Txt文本
/// </summary>
/// <param name="varTextAsset"></param>
/// <param name="varDic"></param>
private void ReadTextAsset(Language varTextAsset, Dictionary<string, string> varDic)
{
string Text;
if (varTextAsset.m_Txt != null)
Text = varTextAsset.m_Txt.text;
else if(varTextAsset.bytes!=null)
Text = System.Text.Encoding.UTF8.GetString(varTextAsset.bytes);
else
Text = varTextAsset.text;
if (string.IsNullOrEmpty(Text))
return;
string temp_Content = Text.Replace("\r\n", "\f");
string[] varContent = temp_Content.Split('\f');
if (varContent == null)
return;
List<string> LanguageList = RemovedNullString(varContent);
if (LanguageList.Count == 0)
return;
for (int i = 0; i < LanguageList.Count; i++)
{
string Temp_Content = LanguageList[i];
if (!Temp_Content.Contains("Text"))
continue;
string Key;
string Value = "";
string[] TempLanguage = Temp_Content.Split('=');
if (TempLanguage.Length < 2)
continue;
Key = TempLanguage[0];
if (!TestingKeyLegal(ref Key))
continue;
for (int jx = 1; jx < TempLanguage.Length; jx++)
{
if (jx == 1)
Value += TempLanguage[jx];
else
Value += "=" + TempLanguage[jx];
}
Value = TestingValueLegal(Value);
if (!varDic.ContainsKey(Key))
varDic.Add(Key, Value);
}
}
/// <summary>
/// 移除数组中无效的字符串
/// </summary>
/// <param name="varContent"></param>
/// <returns></returns>
private List<string> RemovedNullString(string[] varContent)
{
List<string> LanguageList = new List<string>();
for (int i = 0; i < varContent.Length; i++)
{
if (string.IsNullOrEmpty(varContent[i]))
continue;
LanguageList.Add(varContent[i]);
}
return LanguageList;
}
/// <summary>
/// 检测Key的合法性
/// </summary>
/// <param name="Key"></param>
/// <returns></returns>
private bool TestingKeyLegal(ref string Key)
{
//string TempKey = Key;
Key = Key.Trim();
string[] content = Key.Split(' ');
if (content.Length != 2)
return false;
if (content[0] != "Text")
return false;
Key = content[1];
//限制Key值得组成成员
string TestingString = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
char[] tempkey = Key.ToCharArray();
for (int i = 0; i < tempkey.Length; i++)
{
char ms = tempkey[i];
if (!TestingString.Contains(ms.ToString()))
return false;
}
return true;
}
/// <summary>
/// 检测Value值的合法性
/// </summary>
/// <param name="Value"></param>
/// <returns></returns>
private string TestingValueLegal(string Value)
{
//先移除两头无效的空格
Value = Value.Trim();
//当值中存在中括号时,移除两头的中括号
if (Value.Contains("[") && Value.Contains("]"))
{
Value = Value.Trim('[', ']');
}
return Value;
}
private string GetValue(string Key, Dictionary<string, string> varDic)
{
if (!varDic.ContainsKey(Key))
return Key;
string Value = "";
if (varDic.TryGetValue(Key, out Value))
return ClearSpilth(Value);
return Key;
}
/// <summary>
/// 移除多余的字符
/// </summary>
/// <param name="varValue"></param>
/// <returns></returns>
private string ClearSpilth(string varValue)
{
string Value = varValue;
if (Value.Contains("\\n"))
Value = Value.Replace("\\n", "\n");
if (Value.Contains("\\r"))
Value = Value.Replace("\\r", "\r");
if (Value.Contains("\\\\"))
Value = Value.Replace("\\\\", "\\");
if (Value.Contains("\\t"))
Value = Value.Replace("\\t", "\t");
if (Value.Contains("\\v"))
Value = Value.Replace("\\v", "\v");
return Value;
}
/// <summary>
/// 语言结构
/// </summary>
public struct Language
{
/// <summary>
/// 语言类型
/// </summary>
public LanguageType m_Type;
/// <summary>
/// 语言文本
/// </summary>
public TextAsset m_Txt;
/// <summary>
/// 语言文本
/// </summary>
public byte[] bytes;
/// <summary>
/// 语言文本
/// </summary>
public string text;
}
}
该方法在读取解析文本时优先考虑TextAsset、其次时byte[]、最后考虑string类型,实现动态加载就看你是使用什么方式去加载等到文本的内容,只要在调用LanguageManager.Init方法时将语言文本传入即可使用LanguageManager的GetValueToKey方法来获取值信息,从而实现动态加载文字。