做多语言的时候用中文做KEY绝对是有100%的好处,如果用英文表示那么代码里面给文字赋值的地方全都是英文,写的代码多了以后维护起来就没有人能看懂了,或者看起来很费劲。

说说用中文做KEY的原理:Unity中给文字赋值的地方就两处, 一个是提前预制在UI Prefab上的文字,还有一个是写在代码里面的文字。那么在开发阶段我们在Prefab和代码里面直接就写中文,等项目后期通过工具把所有中文的地方全部提取出来。然后把提取出来的中文交给策划,让策划他们去翻译去,这样我们之前写的中文就是多语言的KEY,最终显示的界面上的文字是用这个中文KEY读表读出来的。

NGUI里所有的文字都是在UILabel中,可是我们要做图文混排,一般都是在UILabel上在拓展一个自己的脚本,用这个脚本在生成对应的UILabel和UISprite。这篇文章我就先以UILabel来说明原理。

1.遍历所有UIPrefab把包含UILabe(或者是你自己写的)组件找出来,并且把文字提取出来。

2.遍历所有的CS代码,把所有 StrUtil.GetText(“雨松MOMO\n我要换行“);双引号中间的中文以及字符全部提取出来。

直接上思路代码。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

usingUnityEngine;

usingSystem.Collections;

usingUnityEditor;

usingSystem.Collections.Generic;

usingSystem.IO;

usingSystem.Text;

usingSystem.Text.RegularExpressions;

publicclassTestStart:Editor

{

//UIPrefab文件夹目录

privatestaticstringUIPrefabPath=Application.dataPath+"/UI";

//脚本的文件夹目录

privatestaticstringScriptPath=Application.dataPath+"/Scripts";

//导出的中文KEY路径

privatestaticstringOutPath=Application.dataPath+"/out.txt";

privatestaticListLocalization=null;

privatestaticstringstaticWriteText="";

[MenuItem("Tools/导出多语言")]

staticvoidExportChinese()

{

Localization=newList();

staticWriteText="";

//提取Prefab上的中文

staticWriteText+="----------------Prefab----------------------\n";

LoadDiectoryPrefab(newDirectoryInfo(UIPrefabPath));

//提取CS中的中文

staticWriteText+="----------------Script----------------------\n";

LoadDiectoryCS(newDirectoryInfo(ScriptPath));

//最终把提取的中文生成出来

stringtextPath=OutPath;

if(System.IO.File.Exists(textPath))

{

File.Delete(textPath);

}

using(StreamWriterwriter=newStreamWriter(textPath,false,Encoding.UTF8))

{

writer.Write(staticWriteText);

}

AssetDatabase.Refresh();

}

//递归所有UI Prefab

staticpublicvoidLoadDiectoryPrefab(DirectoryInfodictoryInfo)

{

if(!dictoryInfo.Exists)return;

FileInfo[]fileInfos=dictoryInfo.GetFiles("*.prefab",SearchOption.AllDirectories);

foreach(FileInfofilesinfileInfos)

{

stringpath=files.FullName;

stringassetPath=path.Substring(path.IndexOf("Assets/"));

GameObjectprefab=AssetDatabase.LoadAssetAtPath(assetPath,typeof(GameObject))asGameObject;

GameObjectinstance=GameObject.Instantiate(prefab)asGameObject;

SearchPrefabString(instance.transform);

GameObject.DestroyImmediate(instance);

}

}

//递归所有C#代码

staticpublicvoidLoadDiectoryCS(DirectoryInfodictoryInfo)

{

if(!dictoryInfo.Exists)return;

FileInfo[]fileInfos=dictoryInfo.GetFiles("*.cs",SearchOption.AllDirectories);

foreach(FileInfofilesinfileInfos)

{

stringpath=files.FullName;

stringassetPath=path.Substring(path.IndexOf("Assets/"));

TextAssettextAsset=AssetDatabase.LoadAssetAtPath(assetPath,typeof(TextAsset))asTextAsset;

stringtext=textAsset.text;

//用正则表达式把代码里面两种字符串中间的字符串提取出来。

Regexreg=newRegex("(?<=StrUtil.GetText\\s*\\(\\s*\"\\s*)[\\s\\S]*?(?=\\s*\")");

MatchCollectionmc=reg.Matches(text);

foreach(Matchminmc)

{

stringformat=m.Value;

if(!Localization.Contains(format)&&!string.IsNullOrEmpty(format)){

Localization.Add(format);

staticWriteText+=format+"\n";

}

}

}

}

//提取Prefab上的中文

staticpublicvoidSearchPrefabString(Transformroot)

{

foreach(Transformchindinroot)

{

//因为这里是写例子,所以我用的是UILabel

//这里应该是写你用于图文混排的脚本。

UILabellabel=chind.GetComponent();

if(label!=null)

{

stringtext=label.text;

if(!Localization.Contains(text)&&!string.IsNullOrEmpty(text)){

Localization.Add(text);

text=text.Replace("\n",@"\n");

staticWriteText+=text+"\n";

}

}

if(chind.childCount>0)

SearchPrefabString(chind);

}

}

}

比如这个是个简单界面上赋值的代码。用StrUtil.GetText()去取中文,StrUtiL类是我们自己写的。

1

2

3

4

5

6

7

8

9

10

11

12

usingUnityEngine;

usingSystem.Collections;

publicclassUIMain:MonoBehaviour

{

privateUILabelmName=null;

voidAwake()

{

mName=transform.Find("name").GetComponent();

mName.text=StrUtil.GetText("雨松MOMO\n我要换行");

mName.text=StrUtil.GetText("我是{0}我的网名{1}","宣雨松","雨松MOMO");

}

}

StrUtiL类里面去处理Key从本地数据表里中替换对应多语言显示的文字。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

usingUnityEngine;

usingSystem.Collections;

publicclassStrUtil

{

staticpublicstringGetText(stringtext)

{

//通过传进来的中文KEY 去数据表里面读对应替换的多语言文字

returntext;

}

staticpublicstringGetText(stringtext,paramsobject[]args)

{

//通过传进来的中文KEY 去数据表里面读对应替换的多语言文字

returnstring.Format(text,args);

}

}

使用工具代码提取,最终将所有多语言中文的地方提取在txt里面。

 最后就是让策划拿着生成出来的中文KEY在Excel表里,给出对应的翻译文字。

还有一个重要的知识点就是换行问题,可能你在Prefab上进行的换行的操作,但是\n并不是字符串,所以我们要把\n转成”\n”字符串写进去。

text.Replace(“\n”,@”\n”);

反过来在读取表的时候还是需要再把”\n”字符串转成\n换行符

text.Replace(@”\n”,”\n”);

这样就没问题了。策划也可以直接在数据表里填写\n来进行换行了。

最后的思考

1.开发的过程中可能要修改代码或者要加新功能删功能,所以我们要把差异性的中文Key提取出来,也就是把新增加的KEY 或者 新删除的KEY列举出来。因为没有变化的就不需要策划重新翻译了。

2.最好能直接帮策划生成Excel文件,Windows上很容易,但是MAC就不行。我知道怎么在Mac上读取excel文件,但是我不知道在mac上怎么生成Excel有哪位大神知道还请告知一下我。要能生成.xlsx的那种,谢谢啦。

3.因为要做图文混排,所以UILabel我已经不直接使用了,而是又写了一个类去管理UILable和UISprite, 其实就是根据XML或者JSON 一类的描述符去动态生成UILable和UISprite在帮它的动态的算坐标,算间距 一类的。因为你的中文KEY需要传参数  比如 “我叫{0}我今年{1}大了” 一类的字符串,所以还是在写一个方法。

最后是本文的下载地址,其实本文主要还是提供一个思路。 如果你有对多语言更好的建议,或者是办法,欢迎在下面给我留言,谢谢。

补充, 之前的正则表达式有点问题。因为在代码编写的时候允许中间存在 空格或者换行。 比如下面这样,编译器是不会报错的。。

StrUtil.GetText(“我是222中文”);

StrUtil.GetText ( “22 2222雨松MOMO” );

StrUtil.GetText

(

“222雨松520”

);

所以改一下即可。

1

2

3

4

5

6

stringexpr="(?<=StrUtil.GetText\\s*\\(\\s*\"\\s*)[\\s\\S]*?(?=\\s*\")";

MatchCollectionmc=Regex.Matches(text,expr);

foreach(Matchminmc)

{

Debug.Log(m);

}

最后编辑:2016-05-03作者:雨松MOMO

专注移动互联网,Unity3D游戏开发

捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

python与unity3d语言_Unity3D研究院之多语言用中文做KEY(七十五)相关推荐

  1. 七十五、Python | Leetcode哈希表系列

    @Author:Runsen @Date:2020/7/3 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...

  2. python leetcode_七十五、Python | Leetcode哈希表系列

    @Author:Runsen @Date:2020/7/3 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...

  3. C语言试题七十五之请编写函数求回文数

    1. 题目 编写函数:打印所有不超过n(取n<256)的其平方具有对称性质的数(也称回文数). 2.思路: 把数n的平方用数组保存每位起来,然后反转一次数组,依然是n的平方就是了, 比如:5 平 ...

  4. c++强大还是python强大-Python 到底是强类型语言,还是弱类型语言?

    0.前言 我在上一篇文章中分析了 为什么 Python 没有 void 类型 的话题,在文章发布后,有读者跟我讨论起了另一个关于类型的问题,但是,我们很快就出现了重大分歧. 我们主要的分歧就在于:Py ...

  5. python语言的类型是_Python到底是强类型语言,还是弱类型语言?

    0.前言 我在上一篇文章中分析了 的话题,在文章发布后,有读者跟我讨论起了另一个关于类型的问题,但是,我们很快就出现了重大分歧. 我们主要的分歧就在于:Python 到底是不是强类型语言?我认为是,而 ...

  6. python里两个等号代表什么_Python 到底是强类型语言,还是弱类型语言?

    以下文章来源于 Python 猫 ,作者豌豆花下猫 作者 | 豌豆花下猫 来源 | Python 猫 前言 我在上一篇文章中分析了为什么 Python 没有 void 类型的话题,在文章发布后,有读者 ...

  7. python 强类型 弱类型_Python到底是强类型语言还是弱类型语言

    0.前言 有读者跟我讨论起了另一个关于类型的问题,但是,我们很快就出现了重大分歧. 我们主要的分歧就在于:Python 到底是不是强类型语言?我认为是,而他认为不是. 他写了一篇很长的文章<谁告 ...

  8. 怎么理解python语言是一种强类型语言_Python 到底是强类型语言,还是弱类型语言?...

    0.前言 我在上一篇文章中分析了 为什么 Python 没有 void 类型 的话题,在文章发布后,有读者跟我讨论起了另一个关于类型的问题,但是,我们很快就出现了重大分歧. 我们主要的分歧就在于:Py ...

  9. python是哪种类型的语言-Python到底是强类型语言,还是弱类型语言?

    Python实战社群 Java实战社群 长按识别下方二维码,按需求添加 扫码关注添加客服 进Python社群▲ 扫码关注添加客服 进Java社群▲ 作者丨豌豆花下猫 来源丨Python猫 0.前言 有 ...

最新文章

  1. 桌面笔记工具KeepNote
  2. Oracle database 安装在 Linux(rhel,oel,centos)上的用户设置
  3. c语言构造插值多项式,拉格朗日多项式插值(C语言).docx
  4. 我的网页设计(网页页面制作二)
  5. Java hashCode() 和 equals()的若干问题解答
  6. Hbase如何实现增删查改?
  7. Android 使用WakeLock
  8. 《Joel On Software》读后
  9. 秒懂文件路径 ‘/‘ , ‘./‘ , ‘../‘ 的区别
  10. CTF逆向总结(二)
  11. 开发一款3D场景编辑器
  12. 阿里云大数据工程师(ACP)认证考试大纲
  13. LINUX未来的发展前景
  14. winedit注册码
  15. C++ bit field 位域/位段
  16. Mac电脑为什么适合编程?
  17. 如何表格合并快速简单?
  18. Hadoop与spark性能比较试验
  19. 【芝麻信用对接】欺诈信息验证
  20. app软件系统开发好后有哪些盈利方式?

热门文章

  1. 中国养老产业服务模式与投资盈利前景咨询报告2022版
  2. iOS学习笔记64-Apple Pay编程指南
  3. LumaQQ与IP查询二(转)
  4. 记录使用.netcore 完成微信公众号推送模板消息
  5. 解读大众地平线合作:中国市场纯电车型,单颗芯片全栈方案
  6. 2006世界杯32强人体彩绘队服样式(哥斯达黎加)
  7. 【转】我奋斗了18年才和你坐在一起喝咖啡
  8. 嵌入式~PLC-专辑3
  9. keil的安装以及stm32简单程序的编写与调试
  10. 建筑八大员考试武汉质量员考试滑模施工质量监督检查的重要点