多语言是游戏中比较长见的功能,实现起来也相对比较简单,在这里简单说一下思路,稍后代码附上


简单说一下步骤:

步骤一、设计多语言配置表。在这里说一下多语言配置表。就是一个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>();

// }

//}


}


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


先写到这,有什么错误的地方,欢迎大家留言指正,谢谢!