最近策划反映了个问题,游戏里的多行文本会出现提早换行的问题,以下图所示:布局
文本错误地提早换行,致使第一行文本后面有大块空白区域ui
经过观察能够发现,当字符串中带有半角空格,且半角空格后面的字符串内容超过文本剩余显示宽度时,Text组件会将后面的整段文字作换行。这个并非bug,而是Text组件按照拉丁西语的分词习惯作line break,半角空格至关于分隔符,分隔空格先后的内容,并视之为单词。这种分词规则在西语中是正确的,但用在中文就水土不服了:整段的中文内容,粗暴地按半角空格分红了3部分,第一行空格后面的大段文字被断定为一个单词,剩余宽度没法显示,就被整个换到了第二行。this
稍做思考,尝试使用中文全角空格替换半角空格,换行正常,也就是说,分词规则只对半角空格作处理。然而中文全角空格比半角空格要宽,致使文字间隙过大,显示效果不好。google
那有没有长得跟半角空格同样,而又不会被底层分词的字符呢?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
从这个小问题能够看出Text的分词规则是针对西语而言的,对中文分词支持并很差,好比中文的标点符号不该该出如今行首。若是游戏对中文排版要求比较高,就要考虑本身动手作Text的布局实现了。游戏