版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/CJB_King/article/details/100513905
最近开发的项目要求进行多语言处理,我使用的Unity开发多语言处理具体方案就是,在目标Text添加监听事件以及对应的目标语言文案,当语言改变时触发事件,在语言库中查找对应的文案,进行显示,查找方法我用的是C#的反射原理,下面上代码说明。
[System.Serializable]
public class LanguageType
{
public string LanguageName;
public LanguageInfo languageData;
}
[CreateAssetMenu(menuName = "Configure/LanguageConfigure")]
public class LanguageConfigure : ScriptableObject
{
public LanguageType[] languages;
}
脚本写好后,回到Project目录,选择文件夹,右键“Create->Configure/LanguageConfigure",创建资源文件作为要本地化的语言库,如下所示:
上面的文库填完之后可以直接拿来使用,也可以使用JSON转化工具将其转为JSON文本文件使用,我这里使用的是转为JSON使用的;
public class HelperTool {
[MenuItem("Tools/FileToJsonFile")]
public static void SwitchToJson()
{
Object[] selectedObjs = Selection.GetFiltered(typeof(ScriptableObject), SelectionMode.DeepAssets);
for (int i=0;i<selectedObjs.Length;i++)
{
string rootPath =Application.dataPath+"/Resources/Config/";
Debug.Log(selectedObjs[i].GetType().Name);
string path = rootPath+selectedObjs[i].name+".txt";
string jsonInfo = JsonUtility.ToJson(selectedObjs[i]);
using (FileStream stream = File.Create(path))
{
byte[] array = System.Text.Encoding.UTF8.GetBytes(jsonInfo);
stream.Write(array, 0, array.Length);
AssetDatabase.Refresh();
}
}
}
}
[System.Serializable]
public class LanguageData
{
public LanguageType[] languages;
}
public class LanguageManager : MonoBehaviour
{
private static LanguageManager _mgr = null;
public static LanguageManager _instance
{
get
{
if(_mgr==null)
{
GameObject LanguageManager = new GameObject("LanguageManager");
_mgr = LanguageManager.AddComponent<LanguageManager>();
DontDestroyOnLoad(LanguageManager);
}
return _mgr;
}
}
public delegate void LanguageChanged(string langunagName);
public event LanguageChanged OnLanguageChangedEvent;
private List<LanguageType> LanguageDic;
private LanguageInfo CurrentLanguage;
private void Awake()
{
_mgr = this;
InitLanguageResource();
}
private void Start()
{
ChangeLanguage(PlayerPrefs.GetString(PlayerPrefsManager.LANGUAGE)); //
}
void InitLanguageResource()
{
TextAsset txtLanguage= Resources.Load<TextAsset>("Config/LanguageConfigure");
LanguageData languageConfigure = JsonUtility.FromJson<LanguageData>(txtLanguage.text);
LanguageDic =new List<LanguageType>(languageConfigure.languages);
}
public void ChangeLanguage(string LanguageKey)
{
if(string.IsNullOrEmpty(LanguageKey))
{
LanguageKey = "En";
}
PlayerPrefs.SetString(PlayerPrefsManager.LANGUAGE, LanguageKey);
for (int i=0;i< LanguageDic.Count;i++)
{
if(LanguageDic[i].LanguageName== LanguageKey)
{
CurrentLanguage = LanguageDic[i].languageData;
if(OnLanguageChangedEvent!=null)
OnLanguageChangedEvent(LanguageKey);
}
}
}
public string GetLangeageByKey(string key)
{
FieldInfo[] fieldInfos = CurrentLanguage.GetType().GetFields();
for (int i=0;i< fieldInfos.Length;i++)
{
if (fieldInfos[i].Name == key)
{
return (string)fieldInfos[i].GetValue(CurrentLanguage);
}
}
return null;
}
}
public class LanguageSetListener : MonoBehaviour
{
public string key;
public Font font;
private Font defaultFont;
string Lkey;
void Awake()
{
defaultFont = this.GetComponent<Text>().font;
}
private void Start()
{
LanguageManager._instance.OnLanguageChangedEvent += UpdateLanguage;
Lkey = PlayerPrefs.GetString(PlayerPrefsManager.LANGUAGE);
if (!string.IsNullOrEmpty(Lkey))
{
LanguageManager._instance.ChangeLanguage(Lkey);
}
}
private void OnDestroy()
{
LanguageManager._instance.OnLanguageChangedEvent -= UpdateLanguage;
}
void UpdateLanguage(string LanguageName)
{
string value = LanguageManager._instance.GetLangeageByKey(key);
if(LanguageName.Equals("Ch")&&font!=null)
{
this.GetComponent<Text>().font = this.font;
}
else
{
this.GetComponent<Text>().font = defaultFont;
}
this.GetComponent<Text>().text = value;
}
}
以上是我在项目中使用到的,基于项目特俗要求以及结构所限,写的有点麻烦,不过还是可以使用的,朋友们如果有其他解决方案,欢迎留言分享哦!