unity3d 如何让表情符号显示在Unity TextMeshPro元素中?

wtlkbnrh  于 2023-01-02  发布在  其他
关注(0)|答案(1)|浏览(555)

bounty将在3天后过期。回答此问题可获得+300声望奖励。Mashiro-chan希望引起更多人关注此问题。

我在网上找不到任何关于这个主题的帖子或视频,所以我开始怀疑这是不是不可能。Unity中关于“emojis”的一切都只是一个简单的spritesheet实现,然后用<sprite=0>之类的代码手动索引它们。我正在尝试从Twitter上拉推特,然后用emojis显示它们的文本。所以很明显,这对于unicode支持的1500多个表情符号来说是不可行的。
我相信我已经使用默认的Windows表情符号字体Segoe UI Emoji正确地创建了TMP字体资产,而且看起来使用了我在在线unicode数据库中找到的一些unicode十六进制范围,我能够在字体中检测到1505个表情符号。x1c 0d1x
然后我在项目设置中将表情符号字体设置为后备字体:

但是在运行游戏时,我仍然得到同样的错误The character with Unicode value \uD83D was not found in the [SEGOEUI SDF] font asset or any potential fallbacks. It was replaced by Unicode character \u25A1 in text object
在控制台中,tweet文本的输出如下所示:#cat #cats #CatsOfTwitter #CatsOnTwitter #pet \nLike &amp; share , Thanks!\uD83D\uDE4F\uD83D\uDE4F\uD83D\uDE4F
从网上的一些浏览和unicode的非常基本的知识,我的理论是,问题是在tweet正文中,emoji是在UTF-16代理对或什么,其中\uD83D\uDE4F是一个emoji,但我的emoji字体是UTF-32,所以它在寻找u+0001f64f,那么我是否需要找到一种方法让它读取完整的代理对,然后转换为UTF-32,以获得正确的表情符号来呈现?
任何帮助都将不胜感激,我试着询问周围的统一不和谐服务器,但没有其他人知道如何解决这个问题。

2w3rbyxf

2w3rbyxf1#

简介

TMPro is natively able to do this, but only with UTF-32 formatted unicode. For example, \U0001F600 is '😀︎'. Your emojis are formatted in what I believe is UTF-8 (correct me if i'm wrong), being \u1F600 , which is still '😀︎'. The only difference between these two are the capital U and 3 zeros prepending it. This makes it very easy to convert. Typing the UTF-32 version into TMPro shows the emoji as normal. What you are looking for is converting UTF-16 surrogate pairs into UTF-32, which is included further down.
幸运的是,这个解决方案不需要任何字体修改,默认字体可以做到这一点,我没有改变任何设置在检查器。
UTF-8解决方案
下面的解决方案适用于非代理项对UTF-8代码。
要将UTF-8转换为UTF-32,我们只需要将"u"改为大写,并在前面加上几个零,为此,我们可以使用System.RegularExpressions.Regex.Replace

public string ToUTF32(string input)
{
    string output = input;
    Regex pattern = new Regex(@"\\u[a-zA-Z0-9]*");

    while (output.Contains(@"\u"))
    {
        output = pattern.Replace(output, @"\U000" + output.Substring(output.IndexOf(@"\u", StringComparison.Ordinal) + 2, 5), 1);
    }

    return output;
}

input是包含表情符号unicode的字符串。该函数转换字符串中的所有unicode,并保持其他所有内容不变。

解释

这段代码相当长,所以这是解释。
首先,代码获取输入字符串,例如blah blah \u1F600 blah \u1F603 blah,其中包含2个unicode表情符号,然后用另一个长代码字符串替换unicode,这是下一节。
其次,它接受输入和Substring的所有内容,"\u"后面的5个字符,用"\U000" + the aforementioned string替换文本。
它重复上述步骤,直到所有的unicode都被翻译。
这将输出正确的字符串来完成这项工作。
如果有人认为以上信息不正确,请告诉我。我在这方面的词汇不是最好的,所以我愿意采取更正。

替代对溶液

我已经修修补补了一小会儿,并提出了下面的函数。

public string ToUTF32FromPair(string input)
{
    var output = input;

    Regex pattern = new Regex(@"\\u[a-zA-Z0-9]*\\u[a-zA-Z0-9]*");

    while (output.Contains(@"\u"))
    {
        output = pattern.Replace(output, 
            m => {
                var pair = m.Value;
                var first = pair.Substring(0, 6);
                var second = pair.Substring(6, 6);
                var firstInt = Convert.ToInt32(first.Substring(2), 16);
                var secondInt = Convert.ToInt32(second.Substring(2), 16);
                var codePoint = (firstInt - 0xD800) * 0x400 + (secondInt - 0xDC00) + 0x10000;
                return @"\U" + codePoint.ToString("X8");
            }, 
            1
        );
    }

    return output;
}

这基本上和前面做了相同的事情,只是它接受包含代理对的输入并对其进行翻译。

相关问题