感觉i18n好像用起来不是很方便

已经做好了中文版的游戏,现在准备进行多语言化了,大家都推荐i18n,今天稍微研究了一下,感觉好像不是很方便。比如,中文版项目里有大量地方对Label里面的文字是在代码里面动态处理的,例如像下面这样:
Label.string =‘恭喜您获得了’ + count + ‘颗钻石’;

而i18n似乎不能这样动态的拼接字符串然后赋值给Label的string了吧?我看官方文档里说的是对 LocalizedLabel.dataID 进行赋值(我感觉这个值应该是事先定义好的静态内容)

所以呢,碰上上面这种需要动态拼接字符串处理的逻辑,i18n就无法应对了吧?还是我哪里理解的有问题呢?

请各位老师指教,谢谢!

肯定是你自己的问题。
这种一般都是替换占位符的形式。
比如类似 i18n.t(‘K_TEXT’).replace(’{0}’, count) 这种形式。
自己再去研究下多参数的替换吧

不是 i18n.t(‘K_TEXT’).format(count)吗?我记得是这样的

感谢回复,我还没有下载i18n控件尝试,但大概明白您的意思了,就是可以动态替换占位符,那应该可以解决我的问题。

另外,还有一种情形,感觉i18n应该是无法解决的,比如,大家可能都做过这样的按钮,按钮上面有文字和图标。例如“观看广告领取10颗”钻石,其中“钻石”不是文字,而是个sprite图标。这个时候,如果用i18把“观看广告领取10颗”这段文字替换成其他语言,且先不说替换后语言的长度,是不是刚好能填充到钻石图标前面的位置(我的意思是可能超长或者长度不够,超长会导致文字覆盖钻石图标,长度不够会导致文字和钻石之间有空格),而且换为其他语言后,语序也可能和中文不一样了,例如,日文大概是这样的语序,“观看广告10颗钻石领取”,也就是说钻石图标应该在出现在文字中间才是正确的语序,而不是中文那样钻石图标出现在文字的最后的语序。

上述这种情况我感觉i18n可能无论如何都无法解决吧,还是说我脑子在什么地方绕住了?请多指教,谢谢!

这个不属于本地化的问题了,应该属于图文混排的问题。图文混排一般确实是比较复杂,可能需要自己写组件。

是啊,现在的局面就是窗口中存在很多这样图文混排的按钮或者图文混排的帮助信息。

您说自己重新写组件,那工作量也很大了。我现在的想法是用比较简单粗暴的方法来解决了,不知道这种方法是不是太土了?就是说比如涉及到多语言的窗口,干脆就分别做几个窗口,来对应每种语言。例如GAME_OVER窗口,就做GAME_OVER_CN(中文),GAME_OVER_EN(英文),GAME_OVER_JP(日文)这几种窗口。代码里面用cc.sys.language判断语言,用switch分支处理,是什么语言,就弹出相应的GAME_OVER窗口。反正现在中文版已经做完了,无非就是复制几个窗口,然后在里面直接编辑修改为其他语言就可以了,而且这种方法是可视化编辑,自己可以方便地调整文字和图标这种需要针对当前语言所做的文字长度和图标位置这种细节问题。

似乎也就是初始化场景无法这样分为几个对应语言的窗口(因为初始化场景必须指定死一个窗口是吧),但初始化场景都很简单,就是一个加载进度条和简单几个文字而已,这个在代码里可以很方便地弄成多语言。

您觉得这样怎么样?肯定存在包体变大的问题,但我觉得变大的程度在可接受范围内。也请各位老师多指点,谢谢!

你这想法太夸张了,没必要吧。按理说需要这样混排的label应该不会很多才对,实在不行把这些label复制几个多语言的版本呗,也没必要把整个界面都复制几份吧

可能我这思路确实比较土,但关键我真是没发现i18n那个方法有多方便,自己要定义很多key和值吧?那我干脆就直接分别弄几个语言的窗口得了(因为我的这些窗口里,有非常多的各种文字,图文混排按钮等等)。感觉和自己单弄那个i18n的key和值对应的js文件的工作量也差不多,而且我这方法编辑的时候还完全是可视化编辑,万一有文字长度(或者换行)之类的细微问题立即能发现。

还有,各种音效问题,也存在多语言,都需要走cc.sys.language的switch分支,为了代码统一,干脆就窗口和音效就都保持一致,都走cc.sys.language的switch分支了。

另外,我发现官方文档里说“很抱歉,本文介绍的 i18n 游戏多语言支持这部分内容,目前暂时没有人力维护也很久没有更新了,可能会无法正常运行,建议使用动态加载来自行实现多语言切换功能。”,是不是官方也意识到i18n这种方法有限制或者说不方便的地方呢?
https://docs.cocos.com/creator/manual/zh/advanced-topics/i18n.html#范例项目

等你做大项目的时候就知道了,有几百个界面的那种。界面少的时候随便搞都行,没太大差别。实际上根据我的经验,图文混排的需求是很少的,大部分时候只有聊天框需要做表情才有这需求,其他场合大概都可以通过不同的ui设计来绕过去。

嗯嗯,这个是肯定的,我就是因为项目比较小,感觉用i18n可能反而不太方便。另外,就是我的理解是如果做多语言i18n,那就应该在最初规划的时候规划好。我开始没考虑这么多,现在在中文版已经弄好的时候,这个时候再转i18n,就需要重新为很多节点再引入LocalizedLabel之类的组件,这就很麻烦并且容易造成混乱了。

所以说,目前这种状况,感觉分成几个窗口,可能在处理的时候比较清晰。还有,官方也说“建议使用动态加载来自行实现多语言切换功能”。我不知道官方说的意思是动态加载窗口还是说加载窗口里面的Label或者Sprite组件。如果是动态加载窗口里面的组件,那也相当麻烦了,因为这些组件在中文版里都是直接拖拽编辑的节点,如果要动态加载,那势必要为这些组件都在脚本里关联上变量才能动态加载。那样,脚本代码也变得比较混乱了。所以我感觉动态加载整体的窗口应该比较省事,脚本代码里也就无需再关联各种Label或者Sprite组件。

包体问题,我看了下,我的各种弹窗,比如GAME_OVER,GAME_HELP之类的窗口,都是prefab做的,大概都是100k多些的大小。所以,感觉整个包体的变大的程度可以接受。

自己加个动态赋值的方法不就完了?

我确实没用过i18n,如果还需要引入定制的组件的话确实不方便,我们还是用系统组件,但是给label设置text值的时候通过获取本地化文本的接口。原理上跟i18n是一样的,实现细节略有不同。

不过我还是不建议你用复制窗口的方式来做,未来维护的工作量是比较大的,当你需要调整一些设计的时候。

我看你说的好像有点太拘泥于某种概念了,i18n只不过是internationalization这个词的缩写,又不是什么定死的规则。官方这个只是提供了一种i18n的实现方式而已,不维护估计是这些老demo没人手跟进吧。你完全可以用你觉得方便的方式去实现这个功能

是啊,复制窗口最大的问题就是将来的维护问题。但好在一是现在已经经历很多版本的更新,基本比较稳定了,未来再大幅调整的可能性比较小。还有,虽然是复制窗口,但也仅仅停留在窗口的UI层面,这些窗口关联的JS脚本代码都是一个。

他那个i18n主要是的核心是把文本保存下来,切语言的时候重新把所有保存文本重新赋值而已。其他的都不重要

没错,官方的i18n其实也就是在那个事先定义好的js里面走各种语言的分支。和咱们自己在脚本里面根据语言来给Label的string动态赋值意思也差不多。

其实就是和咱们上次讨论的时候差不多,当时您说的应该是弄个excel文件,里面是key和值,然后弄个方法来根据语言来分别读取。只是我这里图文混排确实占一定的比例。那么如果某些情况是根据key读取,图文混排的情况再用另外一种方式绕过,就感觉不太统一。所以就想出个干脆加载不同语言窗口这么个比较变态的方法。

好在,我的游戏主场景基本不需要多语言化,只是一些游戏结束,游戏设置,游戏帮助这种prefab弹窗的窗口需要。

所以自己有啥需求自己加呗 ,人家只是给你个思路

简单的多语言系统 | Cocos Store这里有款多语言插件,你看合不合适

请问一下这个多语言图片的要怎么配置