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

0x01 问题

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

 608996-20170713171309728-38246241.png
文本错误地提前换行,导致第一行文本后面有大块空白区域

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

608996-20170713173220087-1929059984.png

0x02 解决方案v1

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

608996-20170713181751993-1146170781.png

0x03 解决方案v2

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

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

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

/* ==============================================================================
 * 功能描述:将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!

608996-20170713171217759-427528757.png

0x04 后记

从这个小问题可以看出Text的分词规则是针对西语而言的,对中文分词支持并不好,比如中文的标点符号不应该出现在行首。如果游戏对中文排版要求比较高,就要考虑自己动手做Text的布局实现了。

转载于:https://www.cnblogs.com/leoin2012/p/7162099.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值