Unity 工具类 之 简单的本地化多语言管理类 LanguageDataManager 实现
目录
Unity 工具类 之 简单的本地化多语言管理类 LanguageDataManager 实现
一、简单介绍
Unity 工具类,自己整理的一些游戏开发可能用到的模块,单独独立使用,方便游戏开发。
简单的本地化多语言管理类,单独做了一个单例类,加载管理本地化多语言数据,外界单例调用即可。
二、实现原理
1、单例类,保证整个场景中只有一个类管理本地化多语言数据;
2、文本管理各个国家的语言信息;
3、Resources.Load 把对应的语言信息加载到字典中,进行管理;
4、LanguageDataManager.Instance.SetCurrentLanguageValue(Language) 即可设置语言;
5、LanguageDataManager.Instance.GetLanguageText(languageTextName) 即可获取对应文本信息;
三、注意事项
1、enum 使用枚举,方便后期调用对应的语言和 Text 名称 ;
2、文本多语言信息,建议使用 json 方便后期查阅;
3、注意Txt格式最好是 utf-8 ,不然可能读不到内容;
4、多语言,建议使用抽象类管理,便于后期拓展;
四、效果预览
五、实现步骤
1、打开 Unity,新建工程,导入 文本数据,如下图
2、新建脚本,单例类,语言数据管理类,挂载到UI Text的UI文本名称类,测试类,如下图
3、在场景中,构建简单场景测试,多语言的功能,如下图
4、LanguageUIText 挂载到 UI 对应的 Text 组件上,如下图
5、TestScripts 测试脚本关在到 TestScripts 组件上,并对应赋值,如下图
6、运行场景,效果如下图
六、关键代码
1、TestScripts
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TestScripts : MonoBehaviour
{
// 语言选择
public Toggle Chinese_Toggle;
public Toggle English_Toggle;
void Awake() {
// 语言数据初始化
LanguageDataManager.Instance.Init();
}
// Use this for initialization
void Start()
{
// 绑定事件
if (Chinese_Toggle != null)
{
Chinese_Toggle.onValueChanged.AddListener(SetChineseLanguageIsOn);
}
// 绑定事件
if (English_Toggle != null)
{
English_Toggle.onValueChanged.AddListener(SetEnglishLanguageIsOn);
}
}
/// <summary>
/// 设置语言为中文
/// </summary>
/// <param name="isOn"></param>
private void SetChineseLanguageIsOn(bool isOn)
{
if (isOn == true)
{
SetLanguage(Language.Chinese);
}
}
/// <summary>
/// 设置语言问英文
/// </summary>
/// <param name="isOn"></param>
private void SetEnglishLanguageIsOn(bool isOn)
{
if (isOn == true)
{
SetLanguage(Language.English);
}
}
/// <summary>
/// 设置语言
/// </summary>
/// <param name="language"></param>
private void SetLanguage(Language language)
{
Debug.Log("SetLanguage :" + language);
LanguageDataManager.Instance.SetCurrentLanguageValue(language);
}
}
2、LanguageDataManager
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 存在的语言
/// </summary>
public enum Language
{
Chinese, //中文
English, //英文
}
/// <summary>
/// UI 显示文字的文本信息
/// </summary>
public enum LanguageTextName
{
Chinese_Toggle, //中文Toggle
English_Toggle, //英文Toggle
Text1, // 文本1
Text2, // 文本2
}
public class LanguageDataManager : Singleton<LanguageDataManager>
{
//当前设置的语言
internal Language currentLanguage = Language.Chinese;
// 中英文字典
private Dictionary<string, string> ChineseDictionary = new Dictionary<string, string>();
private Dictionary<string, string> EnglishDictionary = new Dictionary<string, string>();
// 语言资源的文本路径
private static string LANGUAGE_TXT_PATH = "Language/";
/// <summary>
/// 构造函数
/// </summary>
public LanguageDataManager() {
// 加载语言资源
LoadLanguageTxt(Language.Chinese);
LoadLanguageTxt(Language.English);
Debug.Log("LanguageDataManager");
}
/// <summary>
/// 初始化,就是为了 new 构造函数的时候加载 语言资源
/// </summary>
public void Init() { }
/// <summary>
/// 设置语言
/// </summary>
public void SetCurrentLanguageValue(Language language)
{
currentLanguage = language;
//获取场景中所有LanguageUIText类型脚本,用于更新对应语言UI信息
LanguageUIText[] languageUITexts = Resources.FindObjectsOfTypeAll<LanguageUIText>();
Debug.Log("SetCurrentLanguageValue:" + languageUITexts.Length);
for (int i = 0; i < languageUITexts.Length; i++)
{
languageUITexts[i].SetLanguageTextName();
Debug.Log("languageUITexts:" + languageUITexts[i].languageTextName);
}
}
/// <summary>
/// 加载对应的语言资源txt,保存到字典中
/// </summary>
/// <param name="language"></param>
internal void LoadLanguageTxt(Language language)
{
TextAsset ta = Resources.Load<TextAsset>(LANGUAGE_TXT_PATH + language.ToString());
if (ta == null)
{
Debug.Log("没有该语言的文本文件");
return;
}
// 解析文本信息
string[] lines = ta.text.Split('\n');
for (int i = 0; i < lines.Length; i++)
{
if (string.IsNullOrEmpty(lines[i]))
{
continue;
}
string[] kv = lines[i].Split(':');
if (language == Language.Chinese)
{
ChineseDictionary.Add(kv[0], kv[1]);
}
else if (language == Language.English)
{
EnglishDictionary.Add(kv[0], kv[1]);
}
Debug.Log(string.Format("key:{0},value:{1}", kv[0], kv[1]));
}
}
/// <summary>
/// 获得对应语言字典中的对应的 key 值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
internal string GetLanguageText(string key)
{
if (currentLanguage == Language.Chinese)
{
if (ChineseDictionary.ContainsKey(key))
{
return ChineseDictionary[key];
}
else
{
Debug.Log("!ChineseDictionary.ContainsKey(key)");
}
}
else if (currentLanguage == Language.English)
{
if (EnglishDictionary.ContainsKey(key))
{
return EnglishDictionary[key];
}
else
{
Debug.Log("!EnglishDictionary.ContainsKey(key)");
}
}
return string.Empty;
}
}
3、LanguageUIText
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// UI Text 更新的信息
/// </summary>
public class LanguageUIText : MonoBehaviour
{
[SerializeField]
internal LanguageTextName languageTextName;
// Use this for initialization
void Start()
{
// OnEnable 已经设置,可以注释掉
SetLanguageTextName();
}
/// <summary>
/// 脚本使能的使用调用
/// UI 显示的时候 更新文本的对应 Language 信息
/// </summary>
private void OnEnable()
{
SetLanguageTextName();
}
/// <summary>
/// 根据当前语言设置 Text 文本
/// </summary>
internal void SetLanguageTextName()
{
// 获取对应文本的语言对应信息名称
string value = LanguageDataManager.Instance.GetLanguageText(languageTextName.ToString());
// 更新语言信息
if (string.IsNullOrEmpty(value) != true)
{
gameObject.GetComponent<Text>().text = value;
}
}
}
4、Singleton
public abstract class Singleton<T> where T : class, new()
{
private static T instance = null;
// 多线程安全机制
private static readonly object locker = new object();
public static T Instance
{
get
{
lock (locker)
{
if (instance == null)
instance = new T();
return instance;
}
}
}
}
5、文本信息
Chinese.txt
Chinese_Toggle:中文
English_Toggle:英文
Text1:文本 1
Text2:文本 2
分割线--------------------------------------------------
English.txt
Chinese_Toggle:Chinese
English_Toggle:English
Text1:Text 1
Text2:Text 2