10

《Unity3D高级编程之进阶主程》第三章,数据表(三) - 多语言的实现

 3 years ago
source link: http://www.luzexi.com/2018/07/17/Unity3D%E9%AB%98%E7%BA%A7%E7%BC%96%E7%A8%8B%E4%B9%8B%E8%BF%9B%E9%98%B6%E4%B8%BB%E7%A8%8B-%E6%95%B0%E6%8D%AE%E8%A1%A83
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

《Unity3D高级编程之进阶主程》第三章,数据表(三) - 多语言的实现

前文介绍了关于数据表的几种形式,以及如何让数据表运用更加简单高效,这篇我们来讲讲多语言在数据表中的实现方式。

游戏项目中文字显示本身就是件比较头疼的事,再加上多语言,更多的问题将待需解决。很多时候项目起初,文本是写进代码里的,但是当项目中后期,文字又需要由策划来修改和添加,这个导致了大量的程序员的重复工作。所以文字的数据还是放在表里比较好些,就让该考虑文字内容的人去考虑文字内容吧,我们需要把这块工作分离出来,完全交给独立的人处理。

为了实现这个独立模块,我们需要多数据配置表的导出做些规则的设计。

我们来分析下,一般文字放在Excel表里一般都会以Key-Value形式存放,就比如,Key为”RoleName”,Value为”角色名字”,或者Key为1101,Value为”好友分享”等。

这种Key-Value形式,一般会以Int-String形式存在,或者string-string形式存在。

我们先来讨论下这两种形式。

你从数据表里获取文字的方式,你是喜欢以整数为键值还是字符串形式呢?

用整数形式获取就会像这样的样式存在

string content = GetTextString(12)

这种形式,看起来不是很美观,对于其他程序员来说,或者我们过了几周再回头来看时,我们怎么知道12代表什么?只能猜,这个12可能是某个字符串。随着代码的增多文字量的增多,对应数字Key也增多,我们很难识别这句话是代表什么,调试起来会很麻烦。一个项目一般会有10-30万行代码,到处都是这种形式的字符串获取方式,任何人看起来都会崩溃。维护性太差,校验检查难度太大,效率太低。

如果用字符串形式获取

	string content = GetTextString(“FightWin”)

这种形式,会好些吗?看起来似乎好了些,至少我知道了我获取的大概是什么内容的字符串。不过任然有问题,你用一个字符串去获取另一个字符串,那岂不是双份内存,GC垃圾回收的消耗也会同时增加。原本只需要存储一个字符串就够了,现在要存两个,就因为用了键值字符串去获取内容字符串。

当文字内容很多时,我们可能需要用很长的字符串去获取另一个很长的内容,比如用”BattleSceneFightAllianceWin” 去取”联盟战胜利了”,这种形式的字符串换字符串,导致文字数据表变得很大,内存占用量也加大了很多,因为你要另外存一份常量的字符串。

那么我们来想个更好的方法吧,我们既要用简洁的数字去代表文字,又要让键值看起来形象。怎么办?

我们策略是生成一个类,用变量的形式去记录文字的ID,在文字表生成数据表,同时生成数据定义类,使用变量去代表数字。我们依然在表里填字符串对应字符串,比如上面提到的”BattleSceneFightAllianceWin” 对应”联盟战胜利了”,在导出xls数据文件时,生成一个类文件,专门把Key值按次序写进类中当变量。如下

Class TextKey
{
	public const BattleSceneFightAllianceWin = 1;
	public const BattleSceneFightAllianceLose = 2;
}

再把“联盟战胜利了”这种文本数据按次序,依次写入数据文件。这样就可以一一对应了。也就是,第一个变量对应第一个文字,第二个变量对应第二个文字。获取文本的方式改为了

string content = GetTextString(TextKey.BattleSceneFightAllianceWin)

这时文本数据的排列是如下

联盟战胜利了
联盟战失败了
…

而程序变量生成后为如下:

Class TextKey
{
	BattleSceneFightAllianceWin = 1;
	BattleSceneFightAllianceLose = 2;
}

文字与变量的数字依次对应,既解决了用数字做Key不够形象的问题,又解决了字符串做Key太多冗余的问题。

那么多语言部分怎么处理?

简单的处理方式就是做多个表,每个表一个语言。获取方式可以根据不同语言来获取,如下

string content = GetTextString(”win”,Language.Chinese)

不过每次增加删除都要一一对应,否则一个语言没有改就会报错,调试起来非常麻烦。

优化下合并数据表,把一个表里的一个Key对应多个语言的文字内容写在一个表里面。如下

键值  中文  英文  日文   韩文
Win   赢了  Win  勝った 이기다

这样就有了规则,即第2列是中文,第3列是英文,第4列是日文,第5列是韩文,依次类推。

接口没变,任然是

string content = GetTextString(”win”,Language.Chinese)

但是文字表在编辑时就更加的形象,方便,快捷了。

做到这里多语言部分就完美了。策划设计人员和运营人员只要关心文字语言表里内容和键值是否正确就可以了,其他都可以完全交给程序员处理了。

关于分散读取,和集中读取,以及预读取部分,我们也在这里做个讲解。

假如把所有表都集中起来成一个表,那么游戏在加载数据表就需要一次集中使用CPU去处理,导致游戏有时会卡顿现象,不合理。我们需要让游戏表现的尽可能的顺畅。

所以分散读取比较可取,各个表数据都自己管自己读取吧,这样就CPU就分散开来了,不会一下子对CPU的需求量很大。而且在读取数据表时,要按需读取,而不是一开始就初始化,这样的话跟集中在一起就没有区别了。

至于预读取,其实和提前集中读取没有区别,关键是如何利用空挡时间进行预读取。比如在Loading等待时读取一部分数据,这样在等待时也不会浪费CPU。

July 17, 2018 · 书籍著作, Unity3D, 前端技术

感谢您的耐心阅读

Thanks for your reading

版权申明

本文为博主原创文章,未经允许不得转载:

《Unity3D高级编程之进阶主程》第三章,数据表(三) - 多语言的实现

Copyright attention

Please don't reprint without authorize.

qrcode_for_gzh.jpg

微信公众号,文章同步推送,致力于分享一个资深程序员在北上广深拼搏中对世界的理解

QQ交流群: 777859752 (高级程序书友会)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK