Unity3d游戏中实现阿拉伯语文字正常显示

Unity3d游戏中实现阿拉伯语文字正常显示

由于项目需求要把游戏文字显示为维语版本(维语属于阿拉伯语系),我先把维语替换进去,之后发现文字是错的(每个字符都分开了,而且显示方向也不对)后来在网上查了一下发现阿拉伯语是从右往左读的,并且阿拉伯语的32个字符单说写法就有126种(同一个字符有多种写法)如下图:

部分维语字符的不同书写形式

首先我们来了解一下维语:

① 维文是以阿拉伯字母为基层的因素文字,由32个字母构成。分为元音、辅音两大类。
② 8个元音又分三类;3个前元音、3个后元音、2个央元音。 每个词的元音要么都是前元音,要么都是后元音。这8个元音中有4个同汉语元音等值完全相同,有4个相差较大。
③ 24个辅音又分为两类;分别为:10个清音、14个浊音。这24个辅音中有20个同汉语声母辅音等值完全相同,有4个相差较大。
④ 注有“新维文”字样的框格,代表发音相差较大。

书写规则:

【单立式】(又称独立式、独写体)用于词末尾单独构成一个音节时。
【后连式】(又称连首体)用于词首或音节首。
【双连式】(又称前后连式、中连式、连中体)用于两种书写形式的辅音字母之外的其余辅音字母的中间。
【隔音双连式】(又称隔音前后连式)用于词中的音节首。
【前连式】(又称连尾体)用于词末尾与前面的字母相连。
【隔音前连式】用于词末尾与前面的字母连写单独构成一个音节。
【简单单立式】用于词末尾而且是两种书写形式的辅音字母之后。
【简单后连式】用于词中间而且是两种书写形式的辅音字母之后。

上面这都是在网上看到的怎么感觉有点像我们小时候学习 a o e 一样了呢,哈哈.. 不得不说,真的看不懂!

其实看到这些字符我是一脸懵逼,不是龙舟就是战舰的,最主要的是不认识。

最开始我是在网上找了个插件(如果在看到我这篇博客之前你查过阿拉伯语的显示问题,你一定也在GitHub上看到过ArabicSupport这个插件吧),它不过也就是把文字显示方向可以修改过来,但是里边还是存在很多问题的,后来修改了他的源码,这才把项目里的阿拉伯语正常显示出来!当你仔细看他demo源码的时候就会发现,他的做法是把一句话的每个字符分别存到两个数组里,然后用Unicode编码进行比对、替换。打开一个阿拉伯语字体你会看到每一个字符都会有它对应的Unicode编码。如下图:

                      

图一                                                                                                                                   图二

图二中一套字体里为什么会有长得一样的字符呢?点开一个字符,然后左下角你会发现对应的Unicode编码是不同的,并且一个是独立形式,另一个是非独立形式。然而那些错误的字符就是因为使用的非独立形式,才导致再次变形的时候出现错误,我们要做的就是要把这些读取出来的非独立形式转换为独立形式,做好映射

然后在GitHub那个Demo的源码中我们看到他里面提供了几个接口,分别是判断当前字符要使用前连书体、后边书体、还是前后连书体或独立书体,修改代码如下:

  1     /// <summary>
  2     /// Checks if the letter at index value is a leading character in Arabic or not.
  3     /// </summary>
  4     /// <param name="letters">The whole word that contains the character to be checked</param>
  5     /// <param name="index">The index of the character to be checked</param>
  6     /// <returns>True if the character at index is a leading character, else, returns false</returns>
  7     internal static bool IsLeadingLetter(char[] letters, int index)
  8     {
  9
 10         bool lettersThatCannotBeBeforeALeadingLetter = index == 0
 11             || letters[index - 1] == ‘ ‘
 12                 || letters[index - 1] == ‘*‘ // ??? Remove?
 13                 || letters[index - 1] == ‘A‘ // ??? Remove?
 14                 || char.IsPunctuation(letters[index - 1])
 15                 || char.IsNumber(letters[index - 1])
 16                 || letters[index - 1] == ‘>‘
 17                 || letters[index - 1] == ‘<‘
 18                 || letters[index - 1] == (int)IsolatedArabicLetters.Alef
 19                 || letters[index - 1] == (int)IsolatedArabicLetters.Dal
 20                 || letters[index - 1] == (int)IsolatedArabicLetters.Thal
 21                 || letters[index - 1] == (int)IsolatedArabicLetters.Ra2
 22                 || letters[index - 1] == (int)IsolatedArabicLetters.Zeen
 23                 || letters[index - 1] == (int)IsolatedArabicLetters.PersianZe
 24                 //|| letters[index - 1] == (int)IsolatedArabicLetters.AlefMaksora
 25                 || letters[index - 1] == (int)IsolatedArabicLetters.Waw
 26                 || letters[index - 1] == (int)IsolatedArabicLetters.AlefMad
 27                 || letters[index - 1] == (int)IsolatedArabicLetters.AlefHamza
 28                 || letters[index - 1] == (int)IsolatedArabicLetters.AlefMaksoor
 29                 || letters[index - 1] == (int)IsolatedArabicLetters.WawHamza
 30                 || letters[index - 1] == (int)IsolatedArabicLetters.Ae
 31                 || letters[index - 1] == (int)IsolatedArabicLetters.U
 32                 || letters[index - 1] == (int)IsolatedArabicLetters.Yu
 33                 || letters[index - 1] == (int)IsolatedArabicLetters.Oe
 34                 || letters[index - 1] == (int)IsolatedArabicLetters.Ve;
 35
 36         bool lettersThatCannotBeALeadingLetter = letters[index] != ‘ ‘
 37             && letters[index] != (int)IsolatedArabicLetters.Dal
 38             && letters[index] != (int)IsolatedArabicLetters.Thal
 39                 && letters[index] != (int)IsolatedArabicLetters.Ra2
 40                 && letters[index] != (int)IsolatedArabicLetters.Zeen
 41                 && letters[index] != (int)IsolatedArabicLetters.PersianZe
 42                 && letters[index] != (int)IsolatedArabicLetters.Alef
 43                 && letters[index] != (int)IsolatedArabicLetters.AlefHamza
 44                 && letters[index] != (int)IsolatedArabicLetters.AlefMaksoor
 45                 && letters[index] != (int)IsolatedArabicLetters.AlefMad
 46                 && letters[index] != (int)IsolatedArabicLetters.WawHamza
 47                 && letters[index] != (int)IsolatedArabicLetters.Waw
 48                 && letters[index] != (int)IsolatedArabicLetters.Hamza
 49                 && letters[index] != (int)IsolatedArabicLetters.Ae
 50                 && letters[index] != (int)IsolatedArabicLetters.U
 51                 && letters[index] != (int)IsolatedArabicLetters.Yu
 52                 && letters[index] != (int)IsolatedArabicLetters.Oe
 53                 && letters[index] != (int)IsolatedArabicLetters.Ve;
 54
 55         bool lettersThatCannotBeAfterLeadingLetter = index < letters.Length - 1
 56             && letters[index + 1] != ‘ ‘
 57                 && !char.IsPunctuation(letters[index + 1] )
 58                 && !char.IsNumber(letters[index + 1])
 59                 && !char.IsSymbol(letters[index + 1])
 60                 && !char.IsLower(letters[index + 1])
 61                 && !char.IsUpper(letters[index + 1])
 62                 && letters[index + 1] != (int)IsolatedArabicLetters.Hamza;
 63
 64         if(lettersThatCannotBeBeforeALeadingLetter && lettersThatCannotBeALeadingLetter && lettersThatCannotBeAfterLeadingLetter)
 65         {
 66             return true;
 67         }
 68         else
 69             return false;
 70     }
 71
 72     /// <summary>
 73     /// Checks if the letter at index value is a finishing character in Arabic or not.
 74     /// </summary>
 75     /// <param name="letters">The whole word that contains the character to be checked</param>
 76     /// <param name="index">The index of the character to be checked</param>
 77     /// <returns>True if the character at index is a finishing character, else, returns false</returns>
 78     internal static bool IsFinishingLetter(char[] letters, int index)
 79     {
 80         bool indexZero = index != 0;
 81         bool lettersThatCannotBeBeforeAFinishingLetter = (index == 0) ? false :
 82                 letters[index - 1] != ‘ ‘
 83                 && letters[index - 1] != (int)IsolatedArabicLetters.Dal
 84                 && letters[index - 1] != (int)IsolatedArabicLetters.Thal
 85                 && letters[index - 1] != (int)IsolatedArabicLetters.Ra2
 86                 && letters[index - 1] != (int)IsolatedArabicLetters.Zeen
 87                 && letters[index - 1] != (int)IsolatedArabicLetters.PersianZe
 88                 //&& letters[index - 1] != (int)IsolatedArabicLetters.AlefMaksora
 89                 && letters[index - 1] != (int)IsolatedArabicLetters.Waw
 90                 && letters[index - 1] != (int)IsolatedArabicLetters.Alef
 91                 && letters[index - 1] != (int)IsolatedArabicLetters.AlefMad
 92                 && letters[index - 1] != (int)IsolatedArabicLetters.AlefHamza
 93                 && letters[index - 1] != (int)IsolatedArabicLetters.AlefMaksoor
 94                 && letters[index - 1] != (int)IsolatedArabicLetters.WawHamza
 95                 && letters[index - 1] != (int)IsolatedArabicLetters.Hamza
 96                 && letters[index - 1] != (int)IsolatedArabicLetters.Ae
 97                 && letters[index - 1] != (int)IsolatedArabicLetters.U
 98                 && letters[index - 1] != (int)IsolatedArabicLetters.Yu
 99                 && letters[index - 1] != (int)IsolatedArabicLetters.Oe
100                 && letters[index - 1] != (int)IsolatedArabicLetters.Ve
101
102
103                 && !char.IsNumber(letters[index - 1])
104                 && !char.IsPunctuation(letters[index - 1])
105                 && letters[index - 1] != ‘>‘
106                 && letters[index - 1] != ‘<‘;
107
108
109         bool lettersThatCannotBeFinishingLetters = letters[index] != ‘ ‘ && letters[index] != (int)IsolatedArabicLetters.Hamza;
110
111
112
113
114         if(lettersThatCannotBeBeforeAFinishingLetter && lettersThatCannotBeFinishingLetters)
115         {
116             return true;
117         }
118         else
119             return false;
120     }
121
122     /// <summary>
123     /// Checks if the letter at index value is a middle character in Arabic or not.
124     /// </summary>
125     /// <param name="letters">The whole word that contains the character to be checked</param>
126     /// <param name="index">The index of the character to be checked</param>
127     /// <returns>True if the character at index is a middle character, else, returns false</returns>
128     internal static bool IsMiddleLetter(char[] letters, int index)
129     {
130         bool lettersThatCannotBeMiddleLetters = (index == 0) ? false :
131             letters[index] != (int)IsolatedArabicLetters.Alef
132                 && letters[index] != (int)IsolatedArabicLetters.Dal
133                 && letters[index] != (int)IsolatedArabicLetters.Thal
134                 && letters[index] != (int)IsolatedArabicLetters.Ra2
135                 && letters[index] != (int)IsolatedArabicLetters.Zeen
136                 && letters[index] != (int)IsolatedArabicLetters.PersianZe
137                 //&& letters[index] != (int)IsolatedArabicLetters.AlefMaksora
138                 && letters[index] != (int)IsolatedArabicLetters.Waw
139                 && letters[index] != (int)IsolatedArabicLetters.AlefMad
140                 && letters[index] != (int)IsolatedArabicLetters.AlefHamza
141                 && letters[index] != (int)IsolatedArabicLetters.AlefMaksoor
142                 && letters[index] != (int)IsolatedArabicLetters.WawHamza
143                 && letters[index] != (int)IsolatedArabicLetters.Hamza
144                 && letters[index] != (int)IsolatedArabicLetters.Ae
145                 && letters[index] != (int)IsolatedArabicLetters.U
146                 && letters[index] != (int)IsolatedArabicLetters.Yu
147                 && letters[index] != (int)IsolatedArabicLetters.Oe
148                 && letters[index] != (int)IsolatedArabicLetters.Ve;
149
150         bool lettersThatCannotBeBeforeMiddleCharacters = (index == 0) ? false :
151                 letters[index - 1] != (int)IsolatedArabicLetters.Alef
152                 && letters[index - 1] != (int)IsolatedArabicLetters.Dal
153                 && letters[index - 1] != (int)IsolatedArabicLetters.Thal
154                 && letters[index - 1] != (int)IsolatedArabicLetters.Ra2
155                 && letters[index - 1] != (int)IsolatedArabicLetters.Zeen
156                 && letters[index - 1] != (int)IsolatedArabicLetters.PersianZe
157                 //&& letters[index - 1] != (int)IsolatedArabicLetters.AlefMaksora
158                 && letters[index - 1] != (int)IsolatedArabicLetters.Waw
159                 && letters[index - 1] != (int)IsolatedArabicLetters.AlefMad
160                 && letters[index - 1] != (int)IsolatedArabicLetters.AlefHamza
161                 && letters[index - 1] != (int)IsolatedArabicLetters.AlefMaksoor
162                 && letters[index - 1] != (int)IsolatedArabicLetters.WawHamza
163                 && letters[index - 1] != (int)IsolatedArabicLetters.Hamza
164                 && letters[index - 1] != (int)IsolatedArabicLetters.Ae
165                 && letters[index - 1] != (int)IsolatedArabicLetters.U
166                 && letters[index - 1] != (int)IsolatedArabicLetters.Yu
167                 && letters[index - 1] != (int)IsolatedArabicLetters.Oe
168                 && letters[index - 1] != (int)IsolatedArabicLetters.Ve
169                 && !char.IsNumber(letters[index - 1])
170                 && !char.IsPunctuation(letters[index - 1])
171                 && letters[index - 1] != ‘>‘
172                 && letters[index - 1] != ‘<‘
173                 && letters[index - 1] != ‘ ‘
174                 && letters[index - 1] != ‘*‘;
175
176         bool lettersThatCannotBeAfterMiddleCharacters = (index >= letters.Length - 1) ? false :
177             letters[index + 1] != ‘ ‘
178                 && letters[index + 1] != ‘\r‘
179                 && letters[index + 1] != (int)IsolatedArabicLetters.Hamza
180                 && !char.IsNumber(letters[index + 1])
181                 && !char.IsSymbol(letters[index + 1])
182                 && !char.IsPunctuation(letters[index + 1]);
183         if(lettersThatCannotBeAfterMiddleCharacters && lettersThatCannotBeBeforeMiddleCharacters && lettersThatCannotBeMiddleLetters)
184         {
185             try
186             {
187                 if (char.IsPunctuation(letters[index + 1]))
188                     return false;
189                 else
190                     return true;
191             }
192             catch
193             {
194                 return false;
195             }
196             //return true;
197         }
198         else
199             return false;
200     }

对照维语的Unicode编码总结出:

①独立形式Unicode编码的基础之上加1就是前连书体

②独立形式Unicode编码的基础之上加2就是后连书体

③独立形式Unicode编码的基础之上加3就是前后连书体

前面做好映射,有了上面这三个方法就能正常显示字符的书写形式了!(主要就是前连、后连、前后连这几种书写形体,其他形体不再多说)

看一下效果图:(文字看起来是不是舒服一些)

 登录效果图

 

此篇文章经过自己归纳总结整理出来,仅供参考,如果大家有什么好的修改方式,或是好的意见或建议欢迎留言、交流,一起探讨!

原文地址:https://www.cnblogs.com/MrLidx/p/8436089.html

时间: 2024-10-08 09:25:52

Unity3d游戏中实现阿拉伯语文字正常显示的相关文章

Unity3d游戏中添加移动MM支付SDK问题处理

原地址:http://www.tuicool.com/articles/I73QFb 由于移动mm的SDK将部分资源文件放在jar包中,导致Unity无法识别,提示failed to find resource file(mmiap.xml}错误 需要做以下几步操作: -- 解压mmbilling.2.3.0.jar,提取CopyrightDeclaration.xml.mmiap.xml.VERSION文件,和mmiap文件夹 -- 拷贝mmiap文件夹到Unity项目Assets/Plugi

Unity3d 游戏中集成Firebase 统计和Admob广告最新中文教程

Firebase Admob Unity3d插件是一个Unity用户更方便使用Firebase 统计和Firebase admob广告的插件,接口非常的简洁简单,使用c#,无需另外编写java和oc代码一.2种方式安装Firebase Admob Unity3d插件1.直接下载https://github.com/unity-plugins/Firebase-Admob-Unity/ ,然后把Plugins文件夹复制到你Unity3d项目的Plugins目录中2.下载Firebase Admob

Unity3d 游戏中的实时降噪-对Square Enix文档的研究与实现

看到SE的技术文档关于降噪的决定研究一下,本次试验场景: 文章中提到了3中主要滤波方法,最后一种方法又有三种方式分别为Conventional geometry-aware ?ltering,Distribution-Aware Filtering,Specular Lobe-Aware Filtering and Upsampling根据公式做了一些,自己弄得除噪方法不知道是否正确,虽然有效果=  =: 博主的步骤:1.    找出噪波(包括噪波与贴图上的细节)2.    算出specular

Unity3D游戏开发之使用disunity提取Unity3D游戏资源

各位朋友,大家好,我是秦元培.今天博主想和分享的是使用disunity提取Unity3D游戏素材.这个工具呢,博主在Unity3D游戏开发之反编译AssetBundle提取游戏资源这篇文章中其实已经提到过了,不过因为有些朋友对如何使用这个工具依然存在问题,所以博主决定特地写一篇文章来讲解如何使用disunity来提取Unity3D游戏中的素材. 准备工作 disunity:负责对Unity3D的数据文件进行解包 Unity3D:负责将导出的数据文件显示出来 Bleander或者3DsMax:负责

Unity3D 2D游戏中寻径算法的一些解决思路

需求 unity3d的3d开发环境中,原生自带了Navigation的组件,可以很便捷快速的实现寻路功能.但是在原生的2d中并没有相同的功能. 现在国内很多手机游戏都有自动寻路的功能,或者游戏中存在一些例如机器人.npc等,都需要自动寻路的功能. 我需要实现的功能类似于当年FC游戏中淘金者的运动方式.游戏中有淘金者.敌人,可移动,不可移动区域,只能沿着直线的向前向后或者向上向下. 思路 unity3d中也有一些2d寻路的插件.例如A Pathfinding Project Pro和NavMesh

Unity3D RTS游戏中帧同步实现

帧同步技术是早期RTS游戏常用的一种同步技术,本篇文章要给大家介绍的是RTX游戏中帧同步实现,帧同步是一种前后端数据同步的方式,一般应用于对实时性要求很高的网络游戏,想要了解更多帧同步的知识,继续往下看. 一.背景 帧同步技术是早期RTS游戏常用的一种同步技术.与状态同步不同的是,帧同步只同步操作,其大部分游戏逻辑都在客户端上实现,服务器主要负责广播和验证操作,有着逻辑直观易实现.数据量少.可重播等优点. 部分PC游戏如帝国时代.魔兽争霸3.星际争霸等,Host(服务器或某客户端)只当接收到所有

[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(中)

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 喜欢我的博客请记住我的名字:秦元培,我的博客地址是blog.csdn.net/qinyuanpei. 转载请注明出处,本文作者:

【Unity3d游戏开发】Unity3D中的3D数学基础---向量

向量是2D.3D数学研究的标准工具,在3D游戏中向量是基础.因此掌握好向量的一些基本概念以及属性和常用运算方法就显得尤为重要.在本篇博客中,马三就来和大家一起回顾和学习一下Unity3D中那些常用的3D数学知识. 一.向量概念及基本定义 1.向量的数学定义 向量就是一个数字列表,对于程序员来说一个向量就是一个数组. 向量的维度就是向量包含的"数"的数目,向量可以有任意正数维,标量可以被认为是一维向量. 书写向量时,用方括号将一列数括起来,如[1,2,3] 水平书写的向量叫行向量 垂直书

Unity3D游戏开发之C#编程中常见数据结构的比较

一.前言 Unity3D是如今最火爆的游戏开发引擎,它可以让我们能轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型的互动内容.它支持2D/3D游戏开发,据不完全统计,目前国内80%的手机游戏都是用Unity3D开发. 由于Unity3D在开发过程中使用最多的是C# 语言,所以就要合理的使用C#提供的一些数据结构是非常有必要的,合理的选择数据结构可以加快开发速度,提高游戏运行性能,不合理的使用数据结构则会导致游戏运行性能降低,加大开发复杂程度! 先通过表格看看常用的数据结构: C#常用数据