中文里带半角空格致使的Text换行问题[Unity]

0x01 问题

最近策划反映了个问题,游戏里的多行文本会出现提早换行的问题,以下图所示:布局

 
文本错误地提早换行,致使第一行文本后面有大块空白区域ui

经过观察能够发现,当字符串中带有半角空格,且半角空格后面的字符串内容超过文本剩余显示宽度时,Text组件会将后面的整段文字作换行。这个并非bug,而是Text组件按照拉丁西语的分词习惯作line break,半角空格至关于分隔符,分隔空格先后的内容,并视之为单词。这种分词规则在西语中是正确的,但用在中文就水土不服了:整段的中文内容,粗暴地按半角空格分红了3部分,第一行空格后面的大段文字被断定为一个单词,剩余宽度没法显示,就被整个换到了第二行。this

0x02 解决方案v1

稍做思考,尝试使用中文全角空格替换半角空格,换行正常,也就是说,分词规则只对半角空格作处理。然而中文全角空格比半角空格要宽,致使文字间隙过大,显示效果不好。google

0x03 解决方案v2

那有没有长得跟半角空格同样,而又不会被底层分词的字符呢?google一下,找到了答案不换行空格(Non-breaking Space)编码

咱们平时所使用的空格(即键盘Sapce键输出的空格),Unicode编码为/u0020,是换行空格(Breaking Space),空格先后的内容是容许自动换行的;与之对应的不换行空格(Non-breaking space),Unicode编码为/u00A0,显示与换行空格同样,主要用途用于禁止自动换行,在英文中主要用于避免相似(100 KM)这种文字被错误地分词排版成两行。能够说,Breaking Space的存在让西语得以分隔单词,从而正确地分词排版,但放在中文里是多余的存在,中文没有单词概念,不须要作分隔。spa

那这下问题就好解决了,咱们只需在Text组件设置text时,将字符串的换行空格统一更换成不换行空格,就能解决换行错误问题。新建一个NonBreakingSpaceTextComponent类,作文本替换处理:code

/* ==============================================================================
 * 功能描述:将Text组件的space(0x0020)替换为No-break-space(0x00A0),避免中文使用半角空格致使的提早换行问题
 * 创 建 者:shuchangliu
 * ==============================================================================*/

using UnityEngine.UI;
using UnityEngine;

[RequireComponent(typeof(Text))]
public class NonBreakingSpaceTextComponent : MonoBehaviour
{
    public static readonly string no_breaking_space = "\u00A0";

    protected Text text;
    // Use this for initialization
    void Awake ()
    {
        text = this.GetComponent<Text>();
        text.RegisterDirtyVerticesCallback(OnTextChange);
    }

    public void OnTextChange()
    {
        if (text.text.Contains(" "))
        {
            text.text = text.text.Replace(" ", no_breaking_space);
        }
    }

}

将NoBreakingSpaceTextComponent挂在Text组件上,每当Text设置text文字,准备从新绘制Text网格时,NoBreakingSpaceTextComponent会检查并替换text文字里的换行空格。
效果如图所示,Mission Complete!blog

0x04 后记

从这个小问题能够看出Text的分词规则是针对西语而言的,对中文分词支持并很差,好比中文的标点符号不该该出如今行首。若是游戏对中文排版要求比较高,就要考虑本身动手作Text的布局实现了。游戏

相关文章
相关标签/搜索