Unity3d实现阿拉伯语适配,不规则特殊字符的处理。

前言

最近做了阿拉伯语的语言适配。记录一些比较麻烦的点。其实我也没太明白具体和其他语言有什么不同,唯一听懂的就是他们的语序是从右往左的(比如“你好!”,他们的阅读顺序是“!好你”)大概是这样子,具体原理也有很多大神在解释。但可能我没天赋,看的懵懵懂懂索性不去过分理解了。直接用按大神分享的插件就好了。

插件

用了前辈们都推荐的插件Arabic Support for Unity,免费的。没什么可说的。就一句调用代码,demo里面都有。
AssetStore插件地址

使用&问题

这个插件能满足一般的翻译。引用了命名空间的话。一句就够了。

string result = ArabicFixer.Fix(text, false, false);

这能解决一部分问题。
但不巧的是我们的项目需要翻译的比较复杂。因为里面出现了比较多的特殊字符。比如某个约定为切分标记的特殊符号,或者替换标记({}),或者换行符(\n),或者颜色串({str})而且有的是在项目是拼接的颜色串({str})有的是直接在配置表里面配置的颜色串。(这个真是有点醉,因为你不能在输出多语言的时候直接翻译,还需要在项目具体位置拼接完再单独翻译。)
这种的话用这个翻译的就要炸了。
我尝试在翻译的插件里做一些忽略特殊字符之类操作,但因为没理解透彻。反复尝试都有问题。
只能在外部做判断。

下面贴两个比较常用的特殊字符处理方式。

  /// <summary>
        /// 包含换行特殊字符(\n)的处理,优先级高。主要针对多行文字
        /// </summary>
        /// <param name="Str"></param>
        /// <returns></returns>
        public static string ArabicWithRow(string Str)
        {
            Str = Str.Replace(" ", "");
            string[] Holder  = Str.Split('\n');

            string newStr = "";
            for (int i = 0; i < Holder.Length; i++)
            {
                if (Holder[i].Contains("color"))
                {
                    newStr += ArabicWithColor(Holder[i]);
                }
                else
                {
                    newStr += ArabicFixer.Fix(Holder[i], false, false);
                }
                if (i != Holder.Length-1) 
                {
                    newStr += "\n";                 
                }                          
            }
            return newStr;
        }


        /// <summary>
        /// 包含颜色特殊字符的处理优先级低
        /// </summary>
        /// <param name="Str"></param>
        /// <returns></returns>
        public static string ArabicWithColor(string Str)
        {
            Str = Str.Replace(" ", "");
            //根据<>切分
            string[] OldAry = Str.Split(new char[] { '<', '>' });
            //颜色栈
            Stack<string> ColorData = new Stack<string>();
            string tempString = "";
            //颜色部分都用*代替(切分符号)
            for (int i = 0; i < OldAry.Length; i++)
            {
            
                if (OldAry[i].Contains("color"))
                {
                    tempString += "*";
                    if (OldAry[i].Contains("#"))
                    {
                        ColorData.Push(OldAry[i]);
                    }
                }
                else
                {
                    tempString += OldAry[i];
                }
            }
            //翻译字符    
            tempString = ArabicFixer.Fix(tempString, false, false);
         	//通过*切分(切分符号)
            string[] arry = tempString.Split('*');
          
            string newstring = "";
            //拼接
            for (int i = 0; i < arry.Length; i++)
            {

                if (ColorData.Count != 0)
                {
                    if (i % 2 == 0)
                    {
                        newstring += (arry[i] + "<" + ColorData.Pop() + ">");
                    }
                    else
                    {
                        newstring += (arry[i] + "");
                    }
                }
                else
                {
                    if (i == arry.Length - 1)
                    {
                        newstring += (arry[i]);
                    }
                    else
                    {
                        newstring += (arry[i] + "");
                    }
                }
            }
            return newstring;
        }

总结

其实插件对一些特殊字符都是支持的,像\n或者“*”这种都是支持的。但有时候多个特殊字符连续在一起就有可能出错。
而颜色这种({str})不是很规则的字符。直接翻译必错。
所以如果有自己自定义的符号的话,可能需要单独做处理。
不过像这种外面拼接的话还是比较麻烦。有大神能直接改成支持这种字符就好了。

额外注意

切分符号不能出现在被切分的字符串中。
我在做字符拼接时用*切分。是因为我的项目字符串不包含*。如果出现需要切分的字符串里出现*,比如获得 狗崽子*1 这种,就会出问题。(所以标记切分符号的位置大家需要替换成自己项目里字符不包含的字符)
有人建议我在切分前做判断,比如包含*就用@来切分,那么同时包含@和*呢。同时包含@#¥%……&*这些呢,或者判断不包含*就用*切分,那么包含了怎么办?再判断有没有@,再判断有没有@#¥%&*()显然不太合适。
还建议大家约定好使用的特殊字符。

以上。

你可能感兴趣的:(unity3d,多语言,阿拉伯语)