Multilingual support for Unity game
Unity多语言支持
- 零代码,编辑器中就可以完成静态资源的绑定和自动切换
- 所见即所得,编辑器中实时预览不同语言版本切换
- 语言模板,解决多语言翻译语素顺序不一致的文本替换问题
- C#特性支持,使用特性[Language("key")]就可以绑定C#脚本中的变量,实现自动切换语言
- 语言资源基于Addressable,可以运行时下载及更新。也可以和项目自有的ab管理系统并存,互不影响
- 除了切换语言以及LanguageTempalte更新参数的时候,其他时候没有额外性能开销
-
- 打开Unity包管理器,点击+按钮,选择Add package from git url,输入https://github.com/treen/lingguo.git ,点击Add按钮,等待安装完成
-
- 打开lingguo窗口window->Lingguo,在语言栏输入语言包名字,点击Create
- 然后在Assets/Lingguo/下可以看到相应的语言包资产
- 选中Package资产,然后勾选Addressable
-
为了实现语言切换,至少需要创建两个语言包,重复上述步骤创建English
-
- 在场景中添加LingguoConfig节点,挂载LingguoConfig组件,并且添加上述步骤创建的语言包
-
- 选中语言包中的字符串数据库
- 点击ImportDictionary,从CSV文件导入字符串表
- CSV格式为","分割的3列的key,value,comment格式,第3列为注释,可有可无
- 两个#包裹的内容为字符串的引用,会被自动替换为相应语言的Key对应的Value
- 花括号包裹的内容{index}为模板参数,模板会在后面介绍
-
-
创建一个UI面板,添加一个Text组件
-
在Panel节点上添加Language组件,点击"+"按钮添加一个Binder(注意,是Binder,而不是onLanguageChange事件)
- 然后将上述的Text节点拖到绑定对象字段,在成员列表中选中Text.text成员,并且在Key字段选择相应的字符串Key,如hello.lingguo(确保导入的字符串表有该Key)
- 做完上述操作,就能看到UI界面上的文字被替换为了相应语言版本
- 在LingguoConfig中,切换下当前语言为English,可以看到UI文本会立即替换为英文版本,在编辑模式下也是实时变化的
- 也可以绑定其他组件,包括MonoBehavior上的字符串对象,也支持数组,Dropdown的下拉列表类型的绑定
-
注意事项,为了项目容易维护,Language组件限定只能绑定本身及子节点上的对象
-
- 在任何C#类中,都可以在字符串变量上添加[Language]特性来绑定字符串,然后通过LanguageManager.AddLanguageScript函数将类实例添加进管理器,来实现字符串变量的自动替换,管理器使用弱引用,不会影响资源释放,并且只有语言切换的时候才会触发逻辑,其他时候没有任何开销。
- 英文环境下
- 中文环境下
-
- 在字符串库以及LanguageTemplate参数中,都可以使用#key#来引用字符串资源,这样就可以实现当某个key的翻译内容改变时,其他引用这个key的地方会自动改变
- 当上图中,item_knife0001的翻译内容改变时,condition_0001的内容无需修改,会正确显示item_knife0001的翻译
目前支持Sprite,Texture2D,Mesh,AudioClip,Material,以及派生自ScriptObject的资源,可以应付绝大多数多语言资源替换需求。如有不支持的资源,可以选择使用LanguageGameObject组件,进行整个Prefabe的替换
-
-
选中用来切换的sprite,勾选Addressable
-
然后选中相应语言包的AssetDatabase,在Datas下添加相应的资产和Key
- 中文
- 英文
-
然后通过Language,将该key和目标sprite资源进行绑定
- 创建demo按钮
- 使用Language组件将刚才创建的Sprite资产绑定到按钮的image成员上,Language组件可以放在任意需要替换资源的父节点上.比如一个对话框一个Language组件,Language组件放在对话框根节点上,就可以管理该对话框下的所有节点
-
-
-
- 当字符串是动态生成的时候,比如 “某某某”使用“某道具”攻击“某某某”,这样的文本替换需求,就得用模板的动态生成能力了。
-
- 在相应语言包的字符串库中添加模板字符串
- 模板的格式和C#的String.Format一样,以{0},表示第一个参数,{1}表示第二个参数...
- 如果字符串中需要用到花括号,请以**{{**转义
- 注意例子中的模板,中文"{0}"使用"{1}"打了"{2}" 和英文**{0}** attack {2} by {1},第2和第3个参数的位置,顺序是不一样的,这样可以解决多语言翻译中的,语素顺序不一致的问题
- 在资产目录右键菜单Create->Lingguo->Template创建模板资源(这里命名为Attack)
- 选中模板资产,将Key设为刚才添加的attack_somebody,并按照模板参数数量,添加相应的参数,在Inspector面板可以预览生成的结果
- 然后回到最开始的字符串绑定例子,通过Language组件,将绑定类型设为template,然后选择Attack模板作为key绑定目标字符串
- 切换不同语言,可以实时看到,文本会专为相应的语言模板生成
- 在相应的C#脚本中,可以引用这个资产,就像使用Material一样,然后通过LanguageTemplate.SetParams来实时改变参数,并且自动应用到绑定对象上。
- 也可以脱离Language组件,直接在C#脚本中创建LanguageTemplate资产,通过Bind函数进行绑定,SetKey设置相应的字符串模板Key,SetParams设置参数实时更新绑定字符串对象
-
有时候,多语言切换,有些替换无法通过上述步骤完成,比如UI大小,位置的变换,这时候可以选择Prefabe整体替换方案
- 制作不同语言版本的Prefabe资源
- 在根节点上挂载LanguageGameObject组件
- 设置不同语言下使用的Prefabe
- 将该Prefab添加到场景,运行,然后切换语言,就可以看到Prefabe的替换
如果项目本身就使用Addressable的,按照项目Addressable的管理策略管理多语言资源就可以。
如果不熟悉Addressable,项目本身也没有使用Addressable,那么就把多语言资源当做本地资源,打包前,以默认的配置打包Addressable:从菜单打开Window->Asset Manager->Addressable->Groups窗口,点击Build->New Build->Default Build Script。
从Package包导入Sample后,需要将Assets/Samples/Lingguo/版本号/Sample目录下的AddressabeAssetsData目录移动到Assets目录下,才可以正确运行Sample