据说中文和阿拉伯文是两种最难学的语言,中文咱就不说了,来说说阿拉伯文。最近项目要适配阿拉伯文的显示,由于Unity的ugui对阿拉伯文显示并没有提供支持,还是要自己动手来做适配,着实费了一番功夫。本文介绍一下完整的适配方案,供大家一起参考。

阿拉伯文简介

首先介绍下阿拉伯文,阿拉伯文的显示是右对齐、从右到左的,不仅是语序从右到左,就连一个单词的每个字符都是从右到左显示的。打个比方,用大写英文字母来代表阿拉伯字符,我们理解的"ABCD  EFG"(约定下文都用斜粗体表示我们理解的顺序)在阿拉伯文中就会显示成"GFE  DCBA"。

另外,当阿拉伯文和英文、数字混排时,英文和数字的显示顺序又要恢复成从左到右。比如说,我们理解的"ABCD hello world EFG 123"(还是用大写英文字母来代表阿拉伯字符),就会显示成"123 GFE hello world DCBA"。

除了顺序,阿拉伯文还有一个特点是,同一个字符有多种写法,根据这个字符是单词的开头、中间、结尾来选择不同的写法。再打个比方(还是用英文字母举例),字符A有三种写法:A(前连书体),a(前后连书体),(后连书体),那么单词"AAA"就会显示成"aA"。

好了,上述就是阿拉伯文的特点所在,正因为这些与众不同的特点,我们需要经过适配处理才能在Unity中正常显示。

(不得不感慨秦始皇的“书同文”太伟大了)

在哪里适配

网上一些适配方案都是把字符串适配后再赋值给ugui的Text组件,通过修改数据来改变显示。

Text t;
string str;
t.text = ArabicFix(str);

不过我觉得,数据和显示最好分开,所以我把适配放在ugui的Text源码中,在渲染的时候使用适配后的字符串。就是说,Text保存的字符串数据还是从左往右的(如"ABCD hello world EFG 123"),然后转换成从右往左的字符串("123 GFE hello world DCBA"),用后者来渲染。

protect string m_Text = String.Empty;
private string m_ShowText = String.Empty;public virtual string text
{get{return m_Text;}set{...m_Text = value;m_ShowText = ArabicFix(m_Text);...}
}protected override void OnPopulateMesh(VertexHelper toFill)
{...cachedTextGenerator.PopulateWithErrors(m_ShowText, settings, gameObject);...
}

适配方案

完整的适配方案分为5步:字符书体转换、字符串反转、字符串富文本提纯、字符串换行修正、字符串富文本恢复,下面详细说下每个步骤。

字符书体转换

书体转换这一步,我是用的网上的一个开源插件ArabicSupport(https://github.com/Konash/arabic-support-unity),原理就是先判断这个字符是词首,词中还是词尾,然后转换成对应的前连书体、前后连书体、后连书体(这三种书体在Unicode码中有一定规则)。

字符串反转

上面提到的ArabicSupport插件也提供了字符串反转功能,但是略显复杂,效果不是很好,所以我自己重写了一个。很简单,就是用一个栈来处理英文和数字。

string ReverseStr(string str)
{List<char> list = new List<char>{};Stack<char> stack = new Stack<char>{};for(int i = str.Length-1; i >= 0; --i){if()  // 如果是英文字母或者数字,或者是标点符号且前后都是英文或数字,进栈{stack.Push(str[i]);}else{// 遇到阿拉伯字符了,先出栈while(stack.Count > 0){list.Add(stack.Pop());}// 再插入阿拉伯字符list.Add(str[i]);}}// 全部出栈while(stack.Count > 0){list.Add(stack.Pop());}return new string(list.ToArray());
}

字符串换行修正

在说富文本提纯前,先说字符串换行修正。我们知道,ugui的Text组件是有自动换行功能的,但遇到阿拉伯文时,这个换行就出问题了。比如说,显示 "TTTTTTTT 123 GFE hello world DCBA"(从右往左读的阿拉伯字符串),自动换行时,会显示成下图,句首跑到第二行了。

TTTTTTTT 123 GFE
hello world DCBA

这个换行处理ugui没有开源,所以要自己处理,方法是处理字符串时,在适当的地方手动插入换行符'\n'。把"TTTTTTTT 123 GFE hello world DCBA"先处理成"hello world DCBA\nTTTTTTTT 123 GFE ",再用后者渲染,就能得到我们想要的效果。

hello world DCBA
TTTTTTTT 123 GFE

字符串富文本提纯

按照上面的换行修正方法,由于是自己处理字符串,可能会把富文本截断,所以要提取富文本中的纯文本,用纯文本替换掉富文本得到纯文本字符串,然后对纯文本字符串进行换行修正。提取时用到了以下正则式来匹配:

提取富文本:
(<b.+?b>)|(<size.+?size>)|(<color.+?color>)提取富文本中的纯文本:
>[^<>]+<

字符串富文本恢复

经过换行修正后,需要进行富文本的恢复,很简单,在需要恢复的字符子串前后加上富文本修饰词就好。

一个例子

现有一个从左往右读的阿拉伯字符串"ABAB hello world ABA 123"(用大写字母代表阿拉伯字符)

内存中表示为                            ABAB <color=#ff3520>hello world ABA</color> 123

1、字符书体转换                      Aba <color=#ff3520>hello world Ab</color> 123

2、字符串反转                         123 <color/>bA hello world<ff3520#=color> abA      (注意:反转时富文本也会反转)

3、字符串富文本提纯                              123 bA hello world abA

4、字符串换行修正                                 hello world abA\n123 bA

5、字符串富文本恢复    <color=#ff3520> hello world</color> abA\n123 <color=#ff3520>bA</color>

渲染显示                                                        hello world abA

                                                                                            123 bA

写在最后

经测试,这套方案完美解决了项目中的阿拉伯文适配问题。为了避免代码细节喧宾夺主,本文没有贴出代码,只说明了步骤和算法,供大家一起参考。

Unity游戏ugui适配阿拉伯文本显示相关推荐

  1. Unity游戏语音(富文本消息)解决方案GVoice

    Unity游戏语音(富文本消息)解决方案GVoice 腾迅云-GVoice https://www.qcloud.com/document/product/556/7673 集成1-2天内可搞定,博主 ...

  2. Untiy的阿拉伯文本适配

    Unity Text的文本是左往右读,阿拉伯文的文本是右往左读.在复制粘贴之后,可能文本顺序会发生改变.并且通过不Text组件的自动换行的时候会造成换行位置的不正确.在做阿拉伯UI时候需要引入插件处理 ...

  3. unity游戏引擎下的UGUI(2)

    unity游戏引擎下的UGUI(1)unity游戏引擎下的UGUI_m0_57997518的博客-CSDN博客 4.Image Source Image(放图片)(图片要转换为2D and UI) C ...

  4. [Unity3D] Unity3D游戏开发之UGUI实现伤害数值显示

    UGUI实现伤害数值显示的原理是在人物头顶放置空物体,然后将下面的脚本挂在空物体上,将该空物体制作为预制体: using UnityEngine; using System.Collections;p ...

  5. Unity 3D - UGUI 自适应文本框

    Unity 3D - UGUI 自适应文本框 : 说明 : 同一个文本框根据内容 , 自动缩放文本框大小 . 效果图 : 实现方式 ( 重点 ) : 第一步 : 创建一个文本( Text ) , 文本 ...

  6. 【Unity使用UGUI实现王者荣耀UI界面(四)】游戏开始界面

    文章目录 [Unity使用UGUI实现王者荣耀UI界面(四)]游戏开始界面 1. 把一些重复的UI添加 2. 开始游戏按钮 3. 注销按钮 4. 完成 5. 打包 6. 打包完成 内 容 简 介 章节 ...

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

    https://www.cnblogs.com/MrLidx/p/8436089.html Unity3d游戏中实现阿拉伯语文字正常显示 Unity3d游戏中实现阿拉伯语文字正常显示 由于项目需求要把 ...

  8. 随笔:说说第一次在android中嵌入非全屏显示的unity游戏时的坑之——界面切换时出现延迟/卡顿/花屏等现象解决方法

    One 最近对接了个unity3D做的小游戏到android项目中:游戏嵌入项目的界面且非全屏显示,项目几经波折,到我手上的时候,已经采用了在同一个activity中用两个View来分别显示andro ...

  9. Unity UGUI 数字使用图片显示-BMFont

    Unity UGUI 数字使用图片显示-BMFont BMFont 之前使用Cocos引擎的时候需要用到艺术字也就是将数字使用美术给的图片来代替显示,也就是要做一个新字体专门用来显示艺术字,当时用的是 ...

  10. Unity 之 UGUI 图片 和 粒子特效显示层级关系调整

    Unity 之 UGUI 图片 和 粒子特效显示层级关系调整 通常我们使用UGUI时都是通过调整UI的先后顺序或者父物体的层级关系,可是当我使用到粒子特效和Image一起的时候发现光修改层级关系是达不 ...

最新文章

  1. 孙正义看未来30年:这个趋势,永远不会错(附完整PPT)
  2. ECC-based 算法(ECDSA/ECDH) 新潮算法的原理
  3. windows Service循环任务.服务启动后无法停止重启的解决办法
  4. Java面试题:IO流的标准处理异常的代码
  5. 自定义View-实现简易车速器(真的够简易)
  6. Android笔记 采用async http 框架 提交数据到服务器demo
  7. Markdown编辑器中字号、颜色的设置方法及一些好看的颜色示例
  8. OBS-Linux直播神器(录屏神器)
  9. ubuntu下鼠标右键没有新建文档?
  10. window.open 卡死
  11. ofbiz UOM Conversion Relationship Not Found [单位转化关系没有找到] 问题解决:
  12. 图灵、冯诺依曼谁更牛?
  13. 不求星光灿烂,但愿岁月静好
  14. 什么是企业数据?企业工商数据如何获取的。
  15. 物联网概念火热,靠技术如何落地?
  16. 1st Competition of Datawhale: the car price prediction
  17. 2068 Problem M 鸡兔同笼
  18. keil的c语言基础,KeilC单片机C语言应用研究入门基础篇要点S.doc
  19. Centos7挂载ISO镜像
  20. 如何做好技术晋升答辩

热门文章

  1. 最详细的Mysql操作手册(一)
  2. Vayo-CAM365功能详解(二)
  3. 小米高通9008授权服务+Miflash(fh_loader.exe)脚本刷机_icloudelectron
  4. 如何在JavaScript中用SpreadJS导入/导出Excel文件
  5. 水清冷冷:Prcc 2018永久安装图文教程(附工具补丁)
  6. 服务器主板s2600cp2配置Raid5全过程
  7. 易语言对接验证码短信接口DEMO示例
  8. 关于SPSS软件的使用
  9. l3119双闪_打印机进纸灯和墨水灯双灯齐闪 解决方法
  10. 移远BC35-GBC28BC95调试 步骤:从上电到发送一个http请求收到响应