中文里带半角空格导致的Text换行问题[Unity]
0x01 问题##
最近策划反映了个问题,游戏里的多行文本会出现提前换行的问题,如下图所示:
文本错误地提前换行,导致第一行文本后面有大块空白区域
通过观察可以发现,当字符串中带有半角空格,且半角空格后面的字符串内容超过文本剩余显示宽度时,Text组件会将后面的整段文字做换行。这个并不是bug,而是Text组件按照拉丁西语的分词习惯做line break,半角空格相当于分隔符,分隔空格前后的内容,并视之为单词。这种分词规则在西语中是正确的,但用在中文就水土不服了:整段的中文内容,粗暴地按半角空格分成了3部分,第一行空格后面的大段文字被判定为一个单词,剩余宽度无法显示,就被整个换到了第二行。
0x02 解决方案v1##
稍作思考,尝试使用中文全角空格替换半角空格,换行正常,也就是说,分词规则只对半角空格做处理。然而中文全角空格比半角空格要宽,导致文字间隙过大,显示效果很差。
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!
0x04 后记##
从这个小问题可以看出Text的分词规则是针对西语而言的,对中文分词支持并不好,比如中文的标点符号不应该出现在行首。如果游戏对中文排版要求比较高,就要考虑自己动手做Text的布局实现了。
中文里带半角空格导致的Text换行问题[Unity]的更多相关文章
- 全半角空格导致的Sql Server Analysis Services处理错误(转载)
问题描述 某维度表的字符串列同时出现两条记录,A记录以半角空格(英文空格)结束,B记录以全角空格(中文空格)结束,除此之外其他部分均相同.Analysis Service处理的时候抛出“Key not ...
- 关于JAVA正则匹配空白字符的问题(全角空格与半角空格)
今天遇到一个字符串,怎么匹配空格都不成功!!! 我把空格复制到test.properties文件 显示“\u3000” ,这是什么? 这是全角空格!!! 查了一下 \s 不支持全角 1.& ...
- 【trim()】去掉字符串开头和结尾的空格,防止不必要的空格导致的错误。
去掉字符串开头和结尾的空格,防止不必要的空格导致的错误. public static void main(String arg[]){ String a=" abc"; Strin ...
- java去全半角空格,trim(), replaceAll(" +",""),replaceAll("\\s*", ""), replaceAll(" | ", "")
JAVA中去掉空格 . String.trim() trim()是去掉首尾空格 .str.replace(" ", ""); 去掉所有空格,包括首尾.中间 St ...
- JavaScript 正则匹配中文,中文符号,空格,全数字,以https:// 开头的url,用于各种场景的输入校验
业务场景1: 密码输入框需要验证输入中文,中文符号,空格等情况,以便于给出错误提示 业务场景2: 输入框只允许输入数字的情况 业务场景3: 输入框允许输入均为数字或以https:// 开头的url的情 ...
- php中利用正则去掉中文全角空格
一开始用$temp = trim($temp, " "); 这种方法,导致trim后的中文字符有乱码 最后 $str = " 广东君孺律师事务所 "; $str ...
- sql server 去除(替换)空格,回车,换行 函数
--create-- SQL去除回车符,换行符,空格和水平制表符create function RepSymbolChar(@str nvarchar(max))returns nvarchar(ma ...
- java去除字符串中的空格、回车、换行符、制表符
import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @author chzeze * 2016-11-07 */ ...
- 换行符javajava去除字符串中的空格、回车、换行符、制表符
在改章节中,我们主要介绍换行符java的内容,自我感觉有个不错的建议和大家分享下 每日一道理 只有启程,才会到达理想和目的地,只有拼搏,才会获得辉煌的成功,只有播种,才会有收获.只有追求,才会 ...
随机推荐
- stm之SPI通信协议
SPI (Serial Peripheral interface),顾名思义就是串行外围设备接口.SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为P ...
- Win95+IE3 – Win10+IE11全版本执行漏洞(含POC)
微软本月安全更新修复了一个潜藏了18年的IE远程代码执行漏洞(CVE-2014-6332),可以说是给windows吃了一颗大补丸.缺陷出现在VBScript的代码中,自Windows 95首次发布( ...
- AngularJS语法基础及数据绑定——详解各种数据绑定指令、属性应用
AngularJS简单易学,但是功能强大.特别是在构建单页面应用方面效果显著.而 数据绑定 可以说是他被广泛使用的最主要的优点.他舍弃了对DOM的操作方式,一切都由AngularJS来自动更新视图,我 ...
- Java之进程与线程
一.进程 二.线程 1.定义及特点 1)[定义]线程是一个进程内部的一条执行路径,Java虚拟机允许应用程序并发地运行多个执行路径 是系统独立调度和分派[CPU]的基本单位 2)特点 进程中执行运算的 ...
- JavaScript设计模式_01_单例模式
最近项目不太忙,难得有时间看看书,平时挺喜欢js这门语言.也看过很多高级教程,觉得自己还是比较热衷于js的设计模式.这一次重温一下<JavaScript设计模式与开发实践>,开篇为单例模式 ...
- cas单点登录系统:客户端(client)详细配置
最近一直在研究cas登录中心这一块的应用,分享一下记录的一些笔记和心得.后面会把cas-server端的配置和重构,另外还有这几天再搞nginx+cas的https反向代理配置,以及cas的证书相关的 ...
- 【MyBatis源码解析】MyBatis一二级缓存
MyBatis缓存 我们知道,频繁的数据库操作是非常耗费性能的(主要是因为对于DB而言,数据是持久化在磁盘中的,因此查询操作需要通过IO,IO操作速度相比内存操作速度慢了好几个量级),尤其是对于一些相 ...
- (转) Unicode(UTF-8, UTF-16)令人混淆的概念
原文地址:http://www.cnblogs.com/kingcat/archive/2012/10/16/2726334.html 为啥需要Unicode 我们知道计算机其实挺笨的,它只认识010 ...
- SimpleDateFormat日期格式(浅面)
java中使用SimpleDateFormat类的构造函数SimpleDateFormat(String str)构造格式化日期的格式, 通过format(Date date)方法将指定的日期对象格式 ...
- java源码学习(二)Integer
Integer类包含了一个原始基本类型int.Integer属性中就一个属性,它的类型就是int. 此外,这个类还提供了几个把int转成String和把String转成int的方法,同样也提供了其它跟 ...