您的位置:首页 > 移动开发 > Unity3D

unity 多语言管理器

2016-08-11 18:17 387 查看
多语言是游戏中比较长见的功能,实现起来也相对比较简单,在这里简单说一下思路,稍后代码附上

简单说一下步骤:
步骤一、设计多语言配置表。在这里说一下多语言配置表。就是一个json格式文件,每种语言的简写作
为当前语言的键,比如简体用zh-hans,值是一个json对象。比如游戏中有一个需要多语言的
label,内容是“登陆游戏”,我们简单写一下这个表
{
"zh-hans": {
"登陆游戏": "",
" 输入昵称": "",
"攻击力增加{0}%":""

},
"zh-hant": {
"登陆游戏": "登錄遊戲",
"输入昵称": "輸入暱稱",
"攻击力增加{0}%":"攻擊力增加{0}%"
}
}
“zh-hans”表示简体表,“zh-hant”表示繁体表,可能还会有其他语言,比如,英文,德
文,法文等等,都可以加。您可能也注意到了,不管是哪个语言表,他们的键都是简体中文,
这样设计的好处就是直观,后面随着语言的增多,和表中的键值对增多,给键取名也是很难的
事。所以,干脆就是用简体中文作为键,其他的语言都通过它来翻译,这样既直观又省事。
配置表设计好了以后,将游戏各个模块中用到的,需要进行多语言设置的label中的文字,以
label为单位,每个label中的文本作为一对键值,添加到配置表里。这里有一种特殊情况,就
是label中可能有不断变化的数值,例如:“攻击力增加5%”,“英雄获得200金币”等,这样
的情况,这时就不能直接写到配置表里,需要一个字符串格式化处理,例如:“攻击力增加
5%”改为“攻击力增加{0}%”;“英雄获得200金币”改为“英雄获得{0}金币”。在下面的代
码中也提供相应的方法。

步骤二、初始化,主要工作就是解析多语言配置表,加载对应语言的字库。

步骤三、LanguageManager中提供了两个重载的GetValue()方法,游戏中需要多语言显示的label,普
通文本就调用GetValue(string key,UILabel label)方法,有需要格式化字符的label,例
如:“攻击力增加5%”就调用GetValue(string key,UILabel label, params object[]
args),args是可变参数,可以传入数值,int,float,string都可以,如:GetValue("攻击力
增加{0}%",label,5);因为多语言表中可以查到"攻击力增加{0}%"这个键,所以就可以显示出与
当前语言对应的文本。

步骤四、当切换语言的时候,LanguageManager提供了一个ChangeLanguage方法,重新设置当前的
语言键值表,并且发送一个消息,通知所有模块更新本模块内的所有涉及的多语言的label,所
以在各个模块需要监听一个多语言发生改变的事件方法,在方法里重新调用GetValue方法给
label赋值。一般切换语言后需要做一下本地存储,方便玩家下次进入游戏就可以直接进入上次
选择的语言环境。

代码如下:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using LitJson;

public class LanguageManager : Singleton<LanguageManager>
{
private string dataPath = "data/language";
//字体
private Dictionary<string, Font> dicFonts = new Dictionary<string, Font>();
private Dictionary<string, string> dicLanguagePack = new Dictionary<string, string>();
private string currLanguageKey = "";
private JsonData JDAllLanguages = null;
private Dictionary<string, string> dicSupportLanguage = new Dictionary<string, string>();
private Dictionary<int, string> dicLabelsimplifiedKeys = new Dictionary<int, string>();
/// <summary>
/// 获取与当前语言对应的简体中文的键
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
public string GetSimplifiedKey(string val)
{
foreach (KeyValuePair<string, string> kvp in dicLanguagePack)
if (kvp.Value == val)
return kvp.Key;
return string.Empty;
}

public string GetLanguageKey(string val)
{
foreach (KeyValuePair<string,string> kvp in dicSupportLanguage)
if (kvp.Value == val)
return kvp.Key;
return string.Empty;
}

public string GetLanguageVal(string key)
{
if (dicSupportLanguage.ContainsKey(key))
return dicSupportLanguage[key];
return string.Empty;
}

public List<string> GetLanguageValues()
{
List<string> list = new List<string>();

foreach (KeyValuePair<string,string> kvp in dicSupportLanguage)
list.Add(kvp.Value);
return list;
}

public void Init()
{
currLanguageKey = UserData.Instance.CurrentLanguage;

//1.初始化多语言配置表
TextAsset tex = Resources.Load(dataPath) as TextAsset;
string data = tex.text;
Debug.Log("data is " + data);

JDAllLanguages = JsonMapper.ToObject(data);
Debug.Log("jdalllanguages is " + JDAllLanguages.ToJson());
//JsonData jd = JsonMapper.ToObject(data);
if (JDAllLanguages != null)
parse(JDAllLanguages);

dicSupportLanguage.Clear();
dicSupportLanguage.Add("zh-hans", "简体中文");
dicSupportLanguage.Add("zh-hant", "繁体中文");

Font f = Resources.Load("font/hycchj") as Font;
if(!dicFonts.ContainsKey("zh-hans")) dicFonts.Add("zh-hans", f);
f = Resources.Load("font/jingdianfanghei_fanti") as Font;
if (!dicFonts.ContainsKey("zh-hant")) dicFonts.Add("zh-hant", f);
}

void parse(JsonData jd)
{
JsonData jdLan = null;
if (jd.Keys.Contains(currLanguageKey))
jdLan = jd[currLanguageKey];

dicLanguagePack.Clear();
foreach (string key in jdLan.Keys)
if (!dicLanguagePack.ContainsKey(key))
dicLanguagePack.Add(key, jdLan[key].ToString());
}
/// <summary>
/// 切换语言
/// </summary>
/// <param name="lan"></param>
public void ChangeLanguage(string lan)
{
if (UserData.Instance.CurrentLanguage == lan)
return;
UserData.Instance.CurrentLanguage = lan;
currLanguageKey = lan;

RefreshGameLanguagePack();
//应该在这里发送一个语言环境改变的事件通知
MessageController.Instance.SendNotification(MessageTypes.LocalMessageType.LanguageChanged.ToString(), this, null);
}

public string GetValue(string key,UILabel label)
{
if (label)
label.trueTypeFont = GetFont();

if (dicLanguagePack.ContainsKey(key))
{
if (currLanguageKey == "zh-hans")
return key;
else
return dicLanguagePack[key];
}

return key;
}

public string GetValue(string key,UILabel label, params object[] args)
{
if (label)
{
label.trueTypeFont = GetFont();
Debug.Log(label.trueTypeFont.name);
}
return GetValue(key, args);
}

string GetValue(string key, params object[] args)
{
if (dicLanguagePack.ContainsKey(key))
{
if(currLanguageKey == "zh-hans")
return string.Format(key, args);
else
return string.Format(dicLanguagePack[key], args);
}

return key;
}

public Font GetFont()
{
if(dicFonts.ContainsKey(currLanguageKey))
return dicFonts[currLanguageKey];
return null;
}

/// <summary>
/// 更新游戏语言环境,用于玩家切换语言环境
/// </summary>
public void RefreshGameLanguagePack()
{
parse(JDAllLanguages);
}

//给对象添加多语言脚本
//public void AddMulLanguageTextScript(GameObject go)
//{
// if (go == null) return;

// UILabel[] labels = go.GetComponentsInChildren<UILabel>();
// foreach (UILabel item in labels)
// {
// if(item.transform.gameObject.GetComponent<MultiLanguageText>() == null)
// item.transform.gameObject.AddComponent<MultiLanguageText>();
// }
//}

}

这里只出里了文字性的多语言,另外图片也会涉及到多语言,其实都差不多,可以存一下图片的名字,在不同的语言环境调用不同的图片名(或者路径)就可以。

先写到这,有什么错误的地方,欢迎大家留言指正,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  管理器 unity 多语言