最近在做阿语的适配,发现网上并没有一套完整的方案,这次给大家带来一套完整的解决方案,并配上一套可扩展的代码,希望我们每个人以后再遇到阿拉伯语的适配的时候,可以使用这套终极解决方案来搞定。同时随着unity的更新,越来越多项目组使用TextMeshPro。本文提供的方案 既能支持UGUI,也能支持TextmeshPro,还可以从unity2018以上都能适配成功 ,低于这个版本的我没测试。
阿拉伯文的适配最难的点在于,你搞不懂你的结果是对的还是错的,我做的时候就是参考百度翻译,最后再找懂阿语的人来校对一下。文章后面会教给大家一个简单的方法来自己去判断阿语的显示。
1.首先我们要来对阿文有一个基本的认知。阿文的显示是从右往左,右对齐。这里要注意,不只是顺序从右往左,每一个字符,也都是从右往左显示。 原文:"ABCD EFG" (斜体表示原始顺序) 阿文:"GFE DCBA" (非斜体表示正确顺序) 2.阿拉伯语属闪含语系闪米特语族,是由28个辅音字母和12个发音符号(不包括叠音符)组成的拼音文字。书写顺序从右往左横行书写,翻阅顺序也是由右往左。阿拉伯语字母无大、小写之分,但有印刷体、手写体和艺术体之别。书写时,每个字母均有单写与连写之分。 下图为部分辅音字母,简单点说, 28个辅音字母中的每一个都有4个字形,用于根据字母在初始,中间,最终或隔离中的位置来表示字母。(说白了就是,一个字母右4种写法,根据你的位置来决定怎么写,在适配的时候,你会看到一个字符串翻转过来以后,长得完全不一样) 3.tashkeel(元音) 元音我理解就像我们汉字里的拼音,一般来说,是不需要显示元音的。通常在《古兰经》、幼儿读物、阿语学习教材,或者给外国人阅读的书籍中才加元音符号。 一个最简单的看法就是,你发现你的阿文里,上下有点点之类的时候,就表示他显示了元音 大部分情况下,不需要显示原音 4.数字的问题 虽然我们日常使用的是数字叫阿拉伯数字,比如1234567890,但是实际上阿拉伯数字最初由古印度人发明,再由阿拉伯人传向欧洲,欧洲再将其现代化,人们误以为是阿拉伯人发明,所以称之为阿拉伯数 字。实际上阿语中,有一套自己的数字系统,而且不止一套。我们在做阿语适配的时候,会将数值统一改为我们印象中的阿拉伯数字(1234567890),而不用阿拉伯文里数字。 阿拉伯文的数值依然使用从左到右显示 5.和英文,数字等混排的时候,英文和数值依然使用从左到右的顺序 原文:"ABCD hello 123 EFG" (斜体表示原始顺序) 阿文:"GFE 123 hello DCBA" (非斜体表示正确顺序) 以上5种,都是阿语语法和显示顺序的关系,网上有一个免费的插件 也是应用范围最广的一个插件 [https://github.com/Konash/arabic-support-unity](https://github.com/Konash/arabic-support-unity) 该插件使用简单,一句话就可以搞定 string result = ArabicFixer.Fix(text, false, false); 上面这些网上你也能搜索到,实际在项目中使用肯定不会这么简单 这个控件只负责转换阿语的字符,富文本,换行,混排都有些问题 来看一下他的问题 1.换行 2.富文本标签 3.英文,阿语混排 这3种情况,上述插件并不支持,都需要我们对插件做改动。每个项目组都会在自己的理解上做一些改动,但是大家都没有一套统一的解决方案。这里介绍一下我的解决方案。 我这里没有使用ArabicSupport这个插件,而是使用了RTL TextMeshPro这个方案https://github.com/pnarimani/RTLTMPro,这个方案帮我们处理好了富文本标签等效果,可以避免再做一些重复工作了。使用这个方案,再把它的适配效果移植到UGUI。 根据unicode码查询字符 https://symbl.cc/cn/ Unicode字符库 https://www.fuhaoku.net/blocks RTL TextMeshPro https://github.com/pnarimani/RTLTMPro 查看阿语真正正确的顺序 安装好Word软件,不要用WPS,不要用WPS,word软件是为了方便我们验证阿语真正应该显示成什么样子 打开word,复制一句阿语,然后在粘贴选项中选择"只保留文本"。然后选择"段落->从右往左文字方向" 这种状态下,你看到阿语才是真正正确的阿语 重要的事情说3遍:不要相信你在调试的时候,或者是记事本,或者是ide中看到字符串,在实际运行的时候,可能未必是你看到顺序!!! IDE,调试器,或者是一些记事本程序,都会自行对阿语做转换,但是转换的结果未必是正确的!!! 创建一个工具函数,用来打印字符串的unicode码,然后根据unicode码,使用 https://symbl.cc/cn/这个网站来查询对应的字符,才能看到真正的顺序 public void PrintArabicUnicode(string text) StringBuilder sb=new StringBuilder(); for (int i=0;i<text.Length;i++) int unicode32CodePoint = char.ConvertToUtf32(text, i); sb.Append(unicode32CodePoint+" "); Debug.Log(sb.ToString()); //注意在这个文档里,阿语的显示顺序已经发生变化了,其实我使用的还是上面的字符串 //string se = "name_new_group_hint=اسم المجموعة (مطلوب)"; //PrintArabicUnicode(se); //输出结果 //110 97 109 101 95 110 101 119 95 103 114 111 117 112 95 104 105 110 116 61 1575 1587 1605 32 1575 1604 1605 1580 1605 1608 1593 1577 32 40 1605 1591 1604 1608 1576 41 比如说110,对应英文字母n TextMeshPro如何适配 我使用的unity2018.4,TextMeshPro(TMP)版本为1.4.1,这个版本稍微老一些,如果你使用更高级版本的unity和TMP,也可以使用 安装好TMP以后,下载RTL TextMeshPro 打开下载页https://github.com/pnarimani/RTLTMPro/releases,下载 v3.4.3.unitypackage,并且导入到项目中 修改TMP源码 对于TMP2.1以上的版本,都不需要这步,直接第3步即可 低于2.1的版本,需要修改源码。下面介绍一下如何修改TMP的源码 下面是插件官方给的修改方法 如果看不懂的话,按照下面的步骤去修改 首先关闭unity,在Libray/PackageCache中找到TMP源码,然后将整个文件夹剪切到Packages目录中即可 找到TMP_Text文件,给Text字段增加virtual关键字,然后打开 RTLTextMeshPro.cs文件,给Text增加override关键字 使用RTLTMPro 整个文件夹目录如下,Scene中有很多测试的demo,可以看一下,实际在使用的时候,为了节省项目资源,可以只保留Scripts目录,其他目录一律删掉 右键使用菜单时,可以发现多出了Text-RTLTMP的选项 把TextMeshProUGUI脚本,全部替换成RTL TextMeshPro即可 所有需要阿语的文本控件,都替换成RTL TextMeshPro 讲解一下RTL TextMeshPro,它和原生的TextMeshPro比,多出了4个字段 Farsi:勾选以后,英文数字会变成波斯文数字,一般不用勾选ForceFix:这个字段很重要,有时候阿语和英文混排的时候,如果英文字母在句首,往往会把这句话当成英文来处理,这种情况下可以勾选这个选项,来强制使用阿语来处理Preserve Numbers:勾选以后,阿拉伯数字会使用123456789这种形式来显示,建议勾选(具体原因参照上文,阿语中有自己的数字形式,如果想用123456789这种显示数字,就需要勾选)FixTags:勾选后,支持TMP的富文本标签,建议勾选 7.实践中推荐的用法 第6步是官方推荐的用法,在实际应用中发现还是有些不便利的地方,比如说force fix的勾选就不够智能上述4个选项,每次都需要去选择一下,不够智能 下面说一下,我自己是怎么使用的 新建脚本,继承TextMeshProUGUI,这样所有的文本都使用FinalText FinalText会判断字符串中是否包含阿文,如果有阿文,就会自动调用修复脚本来处理 using System.Collections; using System.Collections.Generic; using RTLTMPro; using TMPro; using UnityEngine; public class FinalText : TextMeshProUGUI public override string text get { return base.text; } string val = value; if (HasArabic(val)) isRightToLeftText = true; base.text = GetFixedText(val); isRightToLeftText = false; base.text = val; public static bool HasArabic(string str) if (string.IsNullOrEmpty(str)) return false; int strLength = str.Length; for (var i = 0; i < strLength; i++) char c = str[i]; if (isArabic(c)) return true; return false; public static bool isArabic(char c) if (c >= 0x600 && c <= 0x6ff) return true; if (c >= 0x750 && c <= 0x77f) return true; if (c >= 0xfb50 && c <= 0xfc3f) return true; if (c >= 0xfe70 && c <= 0xfefc) return true; return false; protected readonly FastStringBuilder finalText = new FastStringBuilder(RTLSupport.DefaultBufferSize); private string GetFixedText(string input) if (string.IsNullOrEmpty(input)) return input; finalText.Clear(); RTLSupport.FixRTL(input, finalText, false, true, true); finalText.Reverse(); return finalText.ToString(); 至此,阿语的适配工作基本上就结束了,RTLTMP Pro本身处理了换行,富文本标签,英文阿语混排等问题 UGUI如何适配 上述插件,只支持TMP,对于UGUI就不支持了,查看一下源码发现,不支持的原因主要是因为UGUI不支持RTL的功能,也就是从右向左渲染。 那么如果让UGUI支持这个功能,是不是UGUI也可以用了呢?抱着试试的想法,我做了如下修改,让UGUI的顶点在渲染的时候,把顶点顺序转置 Unity3d游戏中实现阿拉伯语文字正常显示 由于项目需求要把游戏文字显示为维语版本(维语属于阿拉伯语系),我先把维语替换进去,之后发现文字是错的(每个字符都分开了,而且显示方向也不对)后来在网上查了一下发现阿拉伯语是从右往左读的,并且阿拉伯语的32个字符单说写法就有126种(同一个字符有多种写法)如下图: 部分维语字符的不同书写形式 探秘Unity的Right-to-left语言利器:RTL Text Mesh Pro 项目地址:https://gitcode.com/pnarimani/RTLTMPro 在游戏和应用开发中,支持多语言是必不可少的一环,尤其是对于阿拉伯语、波斯语和希伯来语等从右至左(RTL)阅读顺序的语言。现在,让我们一起探索一个专门为Unity设计的强大插件——RTL Text Mesh Pro,它为Tex... 阿拉伯文的读写规则与中文、英文等语言不同,前者是从右往左读的,后者是从左往右读的。而Unity自带的ugui的Text组件是按从左往右来显示的,当需要显示阿拉伯文时,就会导致字符显示顺序不对、自动换行时句序颠倒的问题。本文提供了Unity适配阿拉伯文的解决方案。 Unity Text的文本是左往右读,阿拉伯文的文本是右往左读。在复制粘贴之后,可能文本顺序会发生改变。并且通过不Text组件的自动换行的时候会造成换行位置的不正确。在做阿拉伯UI时候需要引入插件处理 Unity商店里面有两个关于阿拉伯语言适配的免费插件: Arabic Support for Unity Arabic lines support Arabic Support for Unity... 最近做了阿拉伯语的语言适配。记录一些比较麻烦的点。其实我也没太明白具体和其他语言有什么不同,唯一听懂的就是他们的语序是从右往左的(比如“你好!”,他们的阅读顺序是“!好你”)大概是这样子,具体原理也有很多大神在解释。但可能我没天赋,看的懵懵懂懂索性不去过分理解了。直接用按大神分享的插件就好了。 用了前辈们都推荐的插件Arabic Support for Unity,免费的。没什么可说的。就一句调用代码,demo里面都有。 AssetStore插件地址 使用&问题 这个插件能满足一般的翻译 Unity Text的文本是左往右读,阿拉伯文的文本是右往左读。并且通过不Text组件的自动换行的时候会造成换行位置的不正确。用来给多行的阿拉伯文进行修正。之前提到过阿拉伯文字是右往左读的语言,如果直接适应Unity的自动换行,因为语序问题。阿拉伯文的文末将会变成最顶部的一行,而首部则会变成文本的后段。给文本框加上TextFixer,并且在EnterText输入阿拉伯文本,那在这个组件Start()的时候将会调用其方法进行换行的修正。校验后的文本将会变成从右外左的阅读顺序的阿拉伯语言文本。 在某个文件中设置阿语的字符串,但是在设置文本的时候,直接取值显示会出错,需要对字符串进行修改显示。 在AssetsStore中使用一个免费的字符串插件: Arabic Support https://www.assetstore.unity3d.com/en/#!/content/2674 还有一个一直在加新功能,收费的: Easy Alphabet Arabic... 问题描述:涉及金额时需要格式化为0,000.00等格式时,需要用到 DecimalFormat 类进行格式化,但是在应用设置为阿拉伯语后,格式化之后的数字为阿拉伯语的数字格式,如。问题描述:在同一个textview中显示阿拉伯语和数字时,阿拉伯语总是在后面,数字总是在前面,如:金额+货币。劣势:两个textview增加代码工作量,不利于后期维护与扩展。优势:可自由控制显示内容,不会因为阿拉伯语而造成系统强制排序。1,将阿拉伯语与数字拆分成两个textview显示,但是一般都需要按通用数字显示。... 最近,公司要开发一款新的app来面向国际市场,首先推向中东地区用户(阿拉伯语)。 app中有部分功能需要用H5页面来实现,阿拉伯语的页面排版跟中文相反,布局从右向左。其中页面中文字默认右对齐,且从右向左读。
1.首先我们要来对阿文有一个基本的认知。阿文的显示是从右往左,右对齐。这里要注意,不只是顺序从右往左,每一个字符,也都是从右往左显示。 原文:"ABCD EFG" (斜体表示原始顺序) 阿文:"GFE DCBA" (非斜体表示正确顺序) 2.阿拉伯语属闪含语系闪米特语族,是由28个辅音字母和12个发音符号(不包括叠音符)组成的拼音文字。书写顺序从右往左横行书写,翻阅顺序也是由右往左。阿拉伯语字母无大、小写之分,但有印刷体、手写体和艺术体之别。书写时,每个字母均有单写与连写之分。 下图为部分辅音字母,简单点说, 28个辅音字母中的每一个都有4个字形,用于根据字母在初始,中间,最终或隔离中的位置来表示字母。(说白了就是,一个字母右4种写法,根据你的位置来决定怎么写,在适配的时候,你会看到一个字符串翻转过来以后,长得完全不一样) 3.tashkeel(元音) 元音我理解就像我们汉字里的拼音,一般来说,是不需要显示元音的。通常在《古兰经》、幼儿读物、阿语学习教材,或者给外国人阅读的书籍中才加元音符号。 一个最简单的看法就是,你发现你的阿文里,上下有点点之类的时候,就表示他显示了元音 大部分情况下,不需要显示原音 4.数字的问题 虽然我们日常使用的是数字叫阿拉伯数字,比如1234567890,但是实际上阿拉伯数字最初由古印度人发明,再由阿拉伯人传向欧洲,欧洲再将其现代化,人们误以为是阿拉伯人发明,所以称之为阿拉伯数 字。实际上阿语中,有一套自己的数字系统,而且不止一套。我们在做阿语适配的时候,会将数值统一改为我们印象中的阿拉伯数字(1234567890),而不用阿拉伯文里数字。 阿拉伯文的数值依然使用从左到右显示 5.和英文,数字等混排的时候,英文和数值依然使用从左到右的顺序 原文:"ABCD hello 123 EFG" (斜体表示原始顺序) 阿文:"GFE 123 hello DCBA" (非斜体表示正确顺序) 以上5种,都是阿语语法和显示顺序的关系,网上有一个免费的插件 也是应用范围最广的一个插件 [https://github.com/Konash/arabic-support-unity](https://github.com/Konash/arabic-support-unity) 该插件使用简单,一句话就可以搞定 string result = ArabicFixer.Fix(text, false, false); 上面这些网上你也能搜索到,实际在项目中使用肯定不会这么简单 这个控件只负责转换阿语的字符,富文本,换行,混排都有些问题 来看一下他的问题 1.换行 2.富文本标签 3.英文,阿语混排 这3种情况,上述插件并不支持,都需要我们对插件做改动。每个项目组都会在自己的理解上做一些改动,但是大家都没有一套统一的解决方案。这里介绍一下我的解决方案。
上面这些网上你也能搜索到,实际在项目中使用肯定不会这么简单 这个控件只负责转换阿语的字符,富文本,换行,混排都有些问题 来看一下他的问题 1.换行 2.富文本标签 3.英文,阿语混排 这3种情况,上述插件并不支持,都需要我们对插件做改动。每个项目组都会在自己的理解上做一些改动,但是大家都没有一套统一的解决方案。这里介绍一下我的解决方案。
我这里没有使用ArabicSupport这个插件,而是使用了RTL TextMeshPro这个方案https://github.com/pnarimani/RTLTMPro,这个方案帮我们处理好了富文本标签等效果,可以避免再做一些重复工作了。使用这个方案,再把它的适配效果移植到UGUI。 根据unicode码查询字符 https://symbl.cc/cn/ Unicode字符库 https://www.fuhaoku.net/blocks RTL TextMeshPro https://github.com/pnarimani/RTLTMPro 查看阿语真正正确的顺序 安装好Word软件,不要用WPS,不要用WPS,word软件是为了方便我们验证阿语真正应该显示成什么样子 打开word,复制一句阿语,然后在粘贴选项中选择"只保留文本"。然后选择"段落->从右往左文字方向" 这种状态下,你看到阿语才是真正正确的阿语 重要的事情说3遍:不要相信你在调试的时候,或者是记事本,或者是ide中看到字符串,在实际运行的时候,可能未必是你看到顺序!!! IDE,调试器,或者是一些记事本程序,都会自行对阿语做转换,但是转换的结果未必是正确的!!! 创建一个工具函数,用来打印字符串的unicode码,然后根据unicode码,使用 https://symbl.cc/cn/这个网站来查询对应的字符,才能看到真正的顺序 public void PrintArabicUnicode(string text) StringBuilder sb=new StringBuilder(); for (int i=0;i<text.Length;i++) int unicode32CodePoint = char.ConvertToUtf32(text, i); sb.Append(unicode32CodePoint+" "); Debug.Log(sb.ToString()); //注意在这个文档里,阿语的显示顺序已经发生变化了,其实我使用的还是上面的字符串 //string se = "name_new_group_hint=اسم المجموعة (مطلوب)"; //PrintArabicUnicode(se); //输出结果 //110 97 109 101 95 110 101 119 95 103 114 111 117 112 95 104 105 110 116 61 1575 1587 1605 32 1575 1604 1605 1580 1605 1608 1593 1577 32 40 1605 1591 1604 1608 1576 41 比如说110,对应英文字母n TextMeshPro如何适配 我使用的unity2018.4,TextMeshPro(TMP)版本为1.4.1,这个版本稍微老一些,如果你使用更高级版本的unity和TMP,也可以使用 安装好TMP以后,下载RTL TextMeshPro 打开下载页https://github.com/pnarimani/RTLTMPro/releases,下载 v3.4.3.unitypackage,并且导入到项目中 修改TMP源码 对于TMP2.1以上的版本,都不需要这步,直接第3步即可 低于2.1的版本,需要修改源码。下面介绍一下如何修改TMP的源码 下面是插件官方给的修改方法 如果看不懂的话,按照下面的步骤去修改 首先关闭unity,在Libray/PackageCache中找到TMP源码,然后将整个文件夹剪切到Packages目录中即可 找到TMP_Text文件,给Text字段增加virtual关键字,然后打开 RTLTextMeshPro.cs文件,给Text增加override关键字 使用RTLTMPro 整个文件夹目录如下,Scene中有很多测试的demo,可以看一下,实际在使用的时候,为了节省项目资源,可以只保留Scripts目录,其他目录一律删掉 右键使用菜单时,可以发现多出了Text-RTLTMP的选项 把TextMeshProUGUI脚本,全部替换成RTL TextMeshPro即可 所有需要阿语的文本控件,都替换成RTL TextMeshPro 讲解一下RTL TextMeshPro,它和原生的TextMeshPro比,多出了4个字段 Farsi:勾选以后,英文数字会变成波斯文数字,一般不用勾选ForceFix:这个字段很重要,有时候阿语和英文混排的时候,如果英文字母在句首,往往会把这句话当成英文来处理,这种情况下可以勾选这个选项,来强制使用阿语来处理Preserve Numbers:勾选以后,阿拉伯数字会使用123456789这种形式来显示,建议勾选(具体原因参照上文,阿语中有自己的数字形式,如果想用123456789这种显示数字,就需要勾选)FixTags:勾选后,支持TMP的富文本标签,建议勾选 7.实践中推荐的用法 第6步是官方推荐的用法,在实际应用中发现还是有些不便利的地方,比如说force fix的勾选就不够智能上述4个选项,每次都需要去选择一下,不够智能 下面说一下,我自己是怎么使用的 新建脚本,继承TextMeshProUGUI,这样所有的文本都使用FinalText FinalText会判断字符串中是否包含阿文,如果有阿文,就会自动调用修复脚本来处理 using System.Collections; using System.Collections.Generic; using RTLTMPro; using TMPro; using UnityEngine; public class FinalText : TextMeshProUGUI public override string text get { return base.text; } string val = value; if (HasArabic(val)) isRightToLeftText = true; base.text = GetFixedText(val); isRightToLeftText = false; base.text = val; public static bool HasArabic(string str) if (string.IsNullOrEmpty(str)) return false; int strLength = str.Length; for (var i = 0; i < strLength; i++) char c = str[i]; if (isArabic(c)) return true; return false; public static bool isArabic(char c) if (c >= 0x600 && c <= 0x6ff) return true; if (c >= 0x750 && c <= 0x77f) return true; if (c >= 0xfb50 && c <= 0xfc3f) return true; if (c >= 0xfe70 && c <= 0xfefc) return true; return false; protected readonly FastStringBuilder finalText = new FastStringBuilder(RTLSupport.DefaultBufferSize); private string GetFixedText(string input) if (string.IsNullOrEmpty(input)) return input; finalText.Clear(); RTLSupport.FixRTL(input, finalText, false, true, true); finalText.Reverse(); return finalText.ToString(); 至此,阿语的适配工作基本上就结束了,RTLTMP Pro本身处理了换行,富文本标签,英文阿语混排等问题 UGUI如何适配 上述插件,只支持TMP,对于UGUI就不支持了,查看一下源码发现,不支持的原因主要是因为UGUI不支持RTL的功能,也就是从右向左渲染。 那么如果让UGUI支持这个功能,是不是UGUI也可以用了呢?抱着试试的想法,我做了如下修改,让UGUI的顶点在渲染的时候,把顶点顺序转置 Unity3d游戏中实现阿拉伯语文字正常显示 由于项目需求要把游戏文字显示为维语版本(维语属于阿拉伯语系),我先把维语替换进去,之后发现文字是错的(每个字符都分开了,而且显示方向也不对)后来在网上查了一下发现阿拉伯语是从右往左读的,并且阿拉伯语的32个字符单说写法就有126种(同一个字符有多种写法)如下图: 部分维语字符的不同书写形式 探秘Unity的Right-to-left语言利器:RTL Text Mesh Pro 项目地址:https://gitcode.com/pnarimani/RTLTMPro 在游戏和应用开发中,支持多语言是必不可少的一环,尤其是对于阿拉伯语、波斯语和希伯来语等从右至左(RTL)阅读顺序的语言。现在,让我们一起探索一个专门为Unity设计的强大插件——RTL Text Mesh Pro,它为Tex... 阿拉伯文的读写规则与中文、英文等语言不同,前者是从右往左读的,后者是从左往右读的。而Unity自带的ugui的Text组件是按从左往右来显示的,当需要显示阿拉伯文时,就会导致字符显示顺序不对、自动换行时句序颠倒的问题。本文提供了Unity适配阿拉伯文的解决方案。 Unity Text的文本是左往右读,阿拉伯文的文本是右往左读。在复制粘贴之后,可能文本顺序会发生改变。并且通过不Text组件的自动换行的时候会造成换行位置的不正确。在做阿拉伯UI时候需要引入插件处理 Unity商店里面有两个关于阿拉伯语言适配的免费插件: Arabic Support for Unity Arabic lines support Arabic Support for Unity... 最近做了阿拉伯语的语言适配。记录一些比较麻烦的点。其实我也没太明白具体和其他语言有什么不同,唯一听懂的就是他们的语序是从右往左的(比如“你好!”,他们的阅读顺序是“!好你”)大概是这样子,具体原理也有很多大神在解释。但可能我没天赋,看的懵懵懂懂索性不去过分理解了。直接用按大神分享的插件就好了。 用了前辈们都推荐的插件Arabic Support for Unity,免费的。没什么可说的。就一句调用代码,demo里面都有。 AssetStore插件地址 使用&问题 这个插件能满足一般的翻译 Unity Text的文本是左往右读,阿拉伯文的文本是右往左读。并且通过不Text组件的自动换行的时候会造成换行位置的不正确。用来给多行的阿拉伯文进行修正。之前提到过阿拉伯文字是右往左读的语言,如果直接适应Unity的自动换行,因为语序问题。阿拉伯文的文末将会变成最顶部的一行,而首部则会变成文本的后段。给文本框加上TextFixer,并且在EnterText输入阿拉伯文本,那在这个组件Start()的时候将会调用其方法进行换行的修正。校验后的文本将会变成从右外左的阅读顺序的阿拉伯语言文本。 在某个文件中设置阿语的字符串,但是在设置文本的时候,直接取值显示会出错,需要对字符串进行修改显示。 在AssetsStore中使用一个免费的字符串插件: Arabic Support https://www.assetstore.unity3d.com/en/#!/content/2674 还有一个一直在加新功能,收费的: Easy Alphabet Arabic... 问题描述:涉及金额时需要格式化为0,000.00等格式时,需要用到 DecimalFormat 类进行格式化,但是在应用设置为阿拉伯语后,格式化之后的数字为阿拉伯语的数字格式,如。问题描述:在同一个textview中显示阿拉伯语和数字时,阿拉伯语总是在后面,数字总是在前面,如:金额+货币。劣势:两个textview增加代码工作量,不利于后期维护与扩展。优势:可自由控制显示内容,不会因为阿拉伯语而造成系统强制排序。1,将阿拉伯语与数字拆分成两个textview显示,但是一般都需要按通用数字显示。... 最近,公司要开发一款新的app来面向国际市场,首先推向中东地区用户(阿拉伯语)。 app中有部分功能需要用H5页面来实现,阿拉伯语的页面排版跟中文相反,布局从右向左。其中页面中文字默认右对齐,且从右向左读。
我这里没有使用ArabicSupport这个插件,而是使用了RTL TextMeshPro这个方案https://github.com/pnarimani/RTLTMPro,这个方案帮我们处理好了富文本标签等效果,可以避免再做一些重复工作了。使用这个方案,再把它的适配效果移植到UGUI。
根据unicode码查询字符 https://symbl.cc/cn/
Unicode字符库 https://www.fuhaoku.net/blocks
RTL TextMeshPro https://github.com/pnarimani/RTLTMPro
查看阿语真正正确的顺序 安装好Word软件,不要用WPS,不要用WPS,word软件是为了方便我们验证阿语真正应该显示成什么样子 打开word,复制一句阿语,然后在粘贴选项中选择"只保留文本"。然后选择"段落->从右往左文字方向"
这种状态下,你看到阿语才是真正正确的阿语 重要的事情说3遍:不要相信你在调试的时候,或者是记事本,或者是ide中看到字符串,在实际运行的时候,可能未必是你看到顺序!!! IDE,调试器,或者是一些记事本程序,都会自行对阿语做转换,但是转换的结果未必是正确的!!!
创建一个工具函数,用来打印字符串的unicode码,然后根据unicode码,使用 https://symbl.cc/cn/这个网站来查询对应的字符,才能看到真正的顺序
public void PrintArabicUnicode(string text) StringBuilder sb=new StringBuilder(); for (int i=0;i<text.Length;i++) int unicode32CodePoint = char.ConvertToUtf32(text, i); sb.Append(unicode32CodePoint+" "); Debug.Log(sb.ToString()); //注意在这个文档里,阿语的显示顺序已经发生变化了,其实我使用的还是上面的字符串 //string se = "name_new_group_hint=اسم المجموعة (مطلوب)"; //PrintArabicUnicode(se); //输出结果 //110 97 109 101 95 110 101 119 95 103 114 111 117 112 95 104 105 110 116 61 1575 1587 1605 32 1575 1604 1605 1580 1605 1608 1593 1577 32 40 1605 1591 1604 1608 1576 41 比如说110,对应英文字母n TextMeshPro如何适配 我使用的unity2018.4,TextMeshPro(TMP)版本为1.4.1,这个版本稍微老一些,如果你使用更高级版本的unity和TMP,也可以使用 安装好TMP以后,下载RTL TextMeshPro 打开下载页https://github.com/pnarimani/RTLTMPro/releases,下载 v3.4.3.unitypackage,并且导入到项目中 修改TMP源码 对于TMP2.1以上的版本,都不需要这步,直接第3步即可 低于2.1的版本,需要修改源码。下面介绍一下如何修改TMP的源码 下面是插件官方给的修改方法 如果看不懂的话,按照下面的步骤去修改 首先关闭unity,在Libray/PackageCache中找到TMP源码,然后将整个文件夹剪切到Packages目录中即可 找到TMP_Text文件,给Text字段增加virtual关键字,然后打开 RTLTextMeshPro.cs文件,给Text增加override关键字 使用RTLTMPro 整个文件夹目录如下,Scene中有很多测试的demo,可以看一下,实际在使用的时候,为了节省项目资源,可以只保留Scripts目录,其他目录一律删掉 右键使用菜单时,可以发现多出了Text-RTLTMP的选项 把TextMeshProUGUI脚本,全部替换成RTL TextMeshPro即可 所有需要阿语的文本控件,都替换成RTL TextMeshPro 讲解一下RTL TextMeshPro,它和原生的TextMeshPro比,多出了4个字段 Farsi:勾选以后,英文数字会变成波斯文数字,一般不用勾选ForceFix:这个字段很重要,有时候阿语和英文混排的时候,如果英文字母在句首,往往会把这句话当成英文来处理,这种情况下可以勾选这个选项,来强制使用阿语来处理Preserve Numbers:勾选以后,阿拉伯数字会使用123456789这种形式来显示,建议勾选(具体原因参照上文,阿语中有自己的数字形式,如果想用123456789这种显示数字,就需要勾选)FixTags:勾选后,支持TMP的富文本标签,建议勾选 7.实践中推荐的用法 第6步是官方推荐的用法,在实际应用中发现还是有些不便利的地方,比如说force fix的勾选就不够智能上述4个选项,每次都需要去选择一下,不够智能 下面说一下,我自己是怎么使用的 新建脚本,继承TextMeshProUGUI,这样所有的文本都使用FinalText FinalText会判断字符串中是否包含阿文,如果有阿文,就会自动调用修复脚本来处理 using System.Collections; using System.Collections.Generic; using RTLTMPro; using TMPro; using UnityEngine; public class FinalText : TextMeshProUGUI public override string text get { return base.text; } string val = value; if (HasArabic(val)) isRightToLeftText = true; base.text = GetFixedText(val); isRightToLeftText = false; base.text = val; public static bool HasArabic(string str) if (string.IsNullOrEmpty(str)) return false; int strLength = str.Length; for (var i = 0; i < strLength; i++) char c = str[i]; if (isArabic(c)) return true; return false; public static bool isArabic(char c) if (c >= 0x600 && c <= 0x6ff) return true; if (c >= 0x750 && c <= 0x77f) return true; if (c >= 0xfb50 && c <= 0xfc3f) return true; if (c >= 0xfe70 && c <= 0xfefc) return true; return false; protected readonly FastStringBuilder finalText = new FastStringBuilder(RTLSupport.DefaultBufferSize); private string GetFixedText(string input) if (string.IsNullOrEmpty(input)) return input; finalText.Clear(); RTLSupport.FixRTL(input, finalText, false, true, true); finalText.Reverse(); return finalText.ToString(); 至此,阿语的适配工作基本上就结束了,RTLTMP Pro本身处理了换行,富文本标签,英文阿语混排等问题 UGUI如何适配 上述插件,只支持TMP,对于UGUI就不支持了,查看一下源码发现,不支持的原因主要是因为UGUI不支持RTL的功能,也就是从右向左渲染。 那么如果让UGUI支持这个功能,是不是UGUI也可以用了呢?抱着试试的想法,我做了如下修改,让UGUI的顶点在渲染的时候,把顶点顺序转置 Unity3d游戏中实现阿拉伯语文字正常显示 由于项目需求要把游戏文字显示为维语版本(维语属于阿拉伯语系),我先把维语替换进去,之后发现文字是错的(每个字符都分开了,而且显示方向也不对)后来在网上查了一下发现阿拉伯语是从右往左读的,并且阿拉伯语的32个字符单说写法就有126种(同一个字符有多种写法)如下图: 部分维语字符的不同书写形式 探秘Unity的Right-to-left语言利器:RTL Text Mesh Pro 项目地址:https://gitcode.com/pnarimani/RTLTMPro 在游戏和应用开发中,支持多语言是必不可少的一环,尤其是对于阿拉伯语、波斯语和希伯来语等从右至左(RTL)阅读顺序的语言。现在,让我们一起探索一个专门为Unity设计的强大插件——RTL Text Mesh Pro,它为Tex... 阿拉伯文的读写规则与中文、英文等语言不同,前者是从右往左读的,后者是从左往右读的。而Unity自带的ugui的Text组件是按从左往右来显示的,当需要显示阿拉伯文时,就会导致字符显示顺序不对、自动换行时句序颠倒的问题。本文提供了Unity适配阿拉伯文的解决方案。 Unity Text的文本是左往右读,阿拉伯文的文本是右往左读。在复制粘贴之后,可能文本顺序会发生改变。并且通过不Text组件的自动换行的时候会造成换行位置的不正确。在做阿拉伯UI时候需要引入插件处理 Unity商店里面有两个关于阿拉伯语言适配的免费插件: Arabic Support for Unity Arabic lines support Arabic Support for Unity... 最近做了阿拉伯语的语言适配。记录一些比较麻烦的点。其实我也没太明白具体和其他语言有什么不同,唯一听懂的就是他们的语序是从右往左的(比如“你好!”,他们的阅读顺序是“!好你”)大概是这样子,具体原理也有很多大神在解释。但可能我没天赋,看的懵懵懂懂索性不去过分理解了。直接用按大神分享的插件就好了。 用了前辈们都推荐的插件Arabic Support for Unity,免费的。没什么可说的。就一句调用代码,demo里面都有。 AssetStore插件地址 使用&问题 这个插件能满足一般的翻译 Unity Text的文本是左往右读,阿拉伯文的文本是右往左读。并且通过不Text组件的自动换行的时候会造成换行位置的不正确。用来给多行的阿拉伯文进行修正。之前提到过阿拉伯文字是右往左读的语言,如果直接适应Unity的自动换行,因为语序问题。阿拉伯文的文末将会变成最顶部的一行,而首部则会变成文本的后段。给文本框加上TextFixer,并且在EnterText输入阿拉伯文本,那在这个组件Start()的时候将会调用其方法进行换行的修正。校验后的文本将会变成从右外左的阅读顺序的阿拉伯语言文本。 在某个文件中设置阿语的字符串,但是在设置文本的时候,直接取值显示会出错,需要对字符串进行修改显示。 在AssetsStore中使用一个免费的字符串插件: Arabic Support https://www.assetstore.unity3d.com/en/#!/content/2674 还有一个一直在加新功能,收费的: Easy Alphabet Arabic... 问题描述:涉及金额时需要格式化为0,000.00等格式时,需要用到 DecimalFormat 类进行格式化,但是在应用设置为阿拉伯语后,格式化之后的数字为阿拉伯语的数字格式,如。问题描述:在同一个textview中显示阿拉伯语和数字时,阿拉伯语总是在后面,数字总是在前面,如:金额+货币。劣势:两个textview增加代码工作量,不利于后期维护与扩展。优势:可自由控制显示内容,不会因为阿拉伯语而造成系统强制排序。1,将阿拉伯语与数字拆分成两个textview显示,但是一般都需要按通用数字显示。... 最近,公司要开发一款新的app来面向国际市场,首先推向中东地区用户(阿拉伯语)。 app中有部分功能需要用H5页面来实现,阿拉伯语的页面排版跟中文相反,布局从右向左。其中页面中文字默认右对齐,且从右向左读。
我使用的unity2018.4,TextMeshPro(TMP)版本为1.4.1,这个版本稍微老一些,如果你使用更高级版本的unity和TMP,也可以使用 安装好TMP以后,下载RTL TextMeshPro
打开下载页https://github.com/pnarimani/RTLTMPro/releases,下载 v3.4.3.unitypackage,并且导入到项目中
修改TMP源码 对于TMP2.1以上的版本,都不需要这步,直接第3步即可 低于2.1的版本,需要修改源码。下面介绍一下如何修改TMP的源码 下面是插件官方给的修改方法
如果看不懂的话,按照下面的步骤去修改
首先关闭unity,在Libray/PackageCache中找到TMP源码,然后将整个文件夹剪切到Packages目录中即可
找到TMP_Text文件,给Text字段增加virtual关键字,然后打开 RTLTextMeshPro.cs文件,给Text增加override关键字
使用RTLTMPro 整个文件夹目录如下,Scene中有很多测试的demo,可以看一下,实际在使用的时候,为了节省项目资源,可以只保留Scripts目录,其他目录一律删掉 右键使用菜单时,可以发现多出了Text-RTLTMP的选项 把TextMeshProUGUI脚本,全部替换成RTL TextMeshPro即可 所有需要阿语的文本控件,都替换成RTL TextMeshPro
讲解一下RTL TextMeshPro,它和原生的TextMeshPro比,多出了4个字段
7.实践中推荐的用法
第6步是官方推荐的用法,在实际应用中发现还是有些不便利的地方,比如说force fix的勾选就不够智能上述4个选项,每次都需要去选择一下,不够智能 下面说一下,我自己是怎么使用的 新建脚本,继承TextMeshProUGUI,这样所有的文本都使用FinalText FinalText会判断字符串中是否包含阿文,如果有阿文,就会自动调用修复脚本来处理
using System.Collections; using System.Collections.Generic; using RTLTMPro; using TMPro; using UnityEngine; public class FinalText : TextMeshProUGUI public override string text get { return base.text; } string val = value; if (HasArabic(val)) isRightToLeftText = true; base.text = GetFixedText(val); isRightToLeftText = false; base.text = val; public static bool HasArabic(string str) if (string.IsNullOrEmpty(str)) return false; int strLength = str.Length; for (var i = 0; i < strLength; i++) char c = str[i]; if (isArabic(c)) return true; return false; public static bool isArabic(char c) if (c >= 0x600 && c <= 0x6ff) return true; if (c >= 0x750 && c <= 0x77f) return true; if (c >= 0xfb50 && c <= 0xfc3f) return true; if (c >= 0xfe70 && c <= 0xfefc) return true; return false; protected readonly FastStringBuilder finalText = new FastStringBuilder(RTLSupport.DefaultBufferSize); private string GetFixedText(string input) if (string.IsNullOrEmpty(input)) return input; finalText.Clear(); RTLSupport.FixRTL(input, finalText, false, true, true); finalText.Reverse(); return finalText.ToString(); 至此,阿语的适配工作基本上就结束了,RTLTMP Pro本身处理了换行,富文本标签,英文阿语混排等问题 UGUI如何适配 上述插件,只支持TMP,对于UGUI就不支持了,查看一下源码发现,不支持的原因主要是因为UGUI不支持RTL的功能,也就是从右向左渲染。 那么如果让UGUI支持这个功能,是不是UGUI也可以用了呢?抱着试试的想法,我做了如下修改,让UGUI的顶点在渲染的时候,把顶点顺序转置 Unity3d游戏中实现阿拉伯语文字正常显示 由于项目需求要把游戏文字显示为维语版本(维语属于阿拉伯语系),我先把维语替换进去,之后发现文字是错的(每个字符都分开了,而且显示方向也不对)后来在网上查了一下发现阿拉伯语是从右往左读的,并且阿拉伯语的32个字符单说写法就有126种(同一个字符有多种写法)如下图: 部分维语字符的不同书写形式 探秘Unity的Right-to-left语言利器:RTL Text Mesh Pro 项目地址:https://gitcode.com/pnarimani/RTLTMPro 在游戏和应用开发中,支持多语言是必不可少的一环,尤其是对于阿拉伯语、波斯语和希伯来语等从右至左(RTL)阅读顺序的语言。现在,让我们一起探索一个专门为Unity设计的强大插件——RTL Text Mesh Pro,它为Tex... 阿拉伯文的读写规则与中文、英文等语言不同,前者是从右往左读的,后者是从左往右读的。而Unity自带的ugui的Text组件是按从左往右来显示的,当需要显示阿拉伯文时,就会导致字符显示顺序不对、自动换行时句序颠倒的问题。本文提供了Unity适配阿拉伯文的解决方案。 Unity Text的文本是左往右读,阿拉伯文的文本是右往左读。在复制粘贴之后,可能文本顺序会发生改变。并且通过不Text组件的自动换行的时候会造成换行位置的不正确。在做阿拉伯UI时候需要引入插件处理 Unity商店里面有两个关于阿拉伯语言适配的免费插件: Arabic Support for Unity Arabic lines support Arabic Support for Unity... 最近做了阿拉伯语的语言适配。记录一些比较麻烦的点。其实我也没太明白具体和其他语言有什么不同,唯一听懂的就是他们的语序是从右往左的(比如“你好!”,他们的阅读顺序是“!好你”)大概是这样子,具体原理也有很多大神在解释。但可能我没天赋,看的懵懵懂懂索性不去过分理解了。直接用按大神分享的插件就好了。 用了前辈们都推荐的插件Arabic Support for Unity,免费的。没什么可说的。就一句调用代码,demo里面都有。 AssetStore插件地址 使用&问题 这个插件能满足一般的翻译 Unity Text的文本是左往右读,阿拉伯文的文本是右往左读。并且通过不Text组件的自动换行的时候会造成换行位置的不正确。用来给多行的阿拉伯文进行修正。之前提到过阿拉伯文字是右往左读的语言,如果直接适应Unity的自动换行,因为语序问题。阿拉伯文的文末将会变成最顶部的一行,而首部则会变成文本的后段。给文本框加上TextFixer,并且在EnterText输入阿拉伯文本,那在这个组件Start()的时候将会调用其方法进行换行的修正。校验后的文本将会变成从右外左的阅读顺序的阿拉伯语言文本。 在某个文件中设置阿语的字符串,但是在设置文本的时候,直接取值显示会出错,需要对字符串进行修改显示。 在AssetsStore中使用一个免费的字符串插件: Arabic Support https://www.assetstore.unity3d.com/en/#!/content/2674 还有一个一直在加新功能,收费的: Easy Alphabet Arabic... 问题描述:涉及金额时需要格式化为0,000.00等格式时,需要用到 DecimalFormat 类进行格式化,但是在应用设置为阿拉伯语后,格式化之后的数字为阿拉伯语的数字格式,如。问题描述:在同一个textview中显示阿拉伯语和数字时,阿拉伯语总是在后面,数字总是在前面,如:金额+货币。劣势:两个textview增加代码工作量,不利于后期维护与扩展。优势:可自由控制显示内容,不会因为阿拉伯语而造成系统强制排序。1,将阿拉伯语与数字拆分成两个textview显示,但是一般都需要按通用数字显示。... 最近,公司要开发一款新的app来面向国际市场,首先推向中东地区用户(阿拉伯语)。 app中有部分功能需要用H5页面来实现,阿拉伯语的页面排版跟中文相反,布局从右向左。其中页面中文字默认右对齐,且从右向左读。
至此,阿语的适配工作基本上就结束了,RTLTMP Pro本身处理了换行,富文本标签,英文阿语混排等问题
上述插件,只支持TMP,对于UGUI就不支持了,查看一下源码发现,不支持的原因主要是因为UGUI不支持RTL的功能,也就是从右向左渲染。 那么如果让UGUI支持这个功能,是不是UGUI也可以用了呢?抱着试试的想法,我做了如下修改,让UGUI的顶点在渲染的时候,把顶点顺序转置