unity里獲取text中文字寬度并截?cái)嗍÷缘牟僮?/h1>
更新時(shí)間:2021年04月13日 10:13:46 作者:狂云歌
這篇文章主要介紹了unity里獲取text中文字寬度并截?cái)嗍÷缘牟僮?,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
前言
在unity的ugui中Text控件,有時(shí)我們會有各種各樣的需求,比如類似html中css的text-overflow屬性,希望一段文字如果不夠長就全顯示,如果特別長就截?cái)嗖⑶液竺婕由侠纭@種后綴。
好吧這樣的需求在ugui里貌似沒有現(xiàn)成的方法,如果有的話麻煩指點(diǎn)一下~
實(shí)現(xiàn)
大概的思路就是
- 首先要能判斷什么時(shí)候overflow
- 并且支持加上后綴
那么text控件本來是支持overflow然后直接截?cái)嗟?,但是比較暴力,直接砍斷,不能加后綴,并不滿足我們的需求。
然后如果簡單的通過字符個(gè)數(shù)截?cái)啵歉静恍?,如果根?jù)中英文字符來根據(jù)長度截?cái)啵@個(gè)我試過,然而字體并不一定是一個(gè)中文相當(dāng)于倆英文字符,于是乎如果有一大排lllll或者iii什么的,悲劇無以言表。
所以我們需要知道一段文字所對應(yīng)的渲染之后的長度。如果從text的preferwidth或者通過添加content size filter組件應(yīng)該也能完成類似任務(wù),不過我傾向于直接算好長度去填充。
這個(gè)功能核心代碼為
Font myFont = text.font; //chatText is my Text component
myFont.RequestCharactersInTexture(message, text.fontSize, text.fontStyle);
CharacterInfo characterInfo = new CharacterInfo();
char[] arr = message.ToCharArray();
foreach (char c in arr)
{
myFont.GetCharacterInfo(c, out characterInfo, text.fontSize);
totalLength += characterInfo.advance;
}
其中text為Text文本控件,RequestCharactersInTexture主要相當(dāng)于指定需要渲染哪些字符(然后根據(jù)CharacterInfo.characterInfo是可以拿到本次生成的去重后的字符集)。接下來通過myFont.GetCharacterInfo(c, out characterInfo, text.fontSize);分別去獲得每個(gè)字符的信息,然后characterInfo.advance就拿到了每個(gè)字符的渲染長度。
拿到每個(gè)字符長度之后那就簡單多了,計(jì)算一下需要截?cái)嗟淖址傞L度,如果大于限制長度,就除去后綴長度后,截取子字符串,然后再接上后綴。這個(gè)事情就搞定了。
全部如下,這個(gè)例子是需要一個(gè)text和一個(gè)button,點(diǎn)擊button,隨機(jī)生成文字在text上。
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class TextWidth : MonoBehaviour {
public Text text;
public Button button;
const string suffix = "...";
const int MAX_WIDTH = 200;
int suffixWidth = 0;
string[] seeds = { "是都", "60°", "qの", "【】" , "d a", "as", "WW", "II", "fs", "as", "WW", "II", "fs" };
// Use this for initialization
void Start () {
Init();
button.onClick.AddListener(Rand);
}
void Init()
{
//計(jì)算后綴的長度
suffixWidth = CalculateLengthOfText(suffix);
Debug.Log("suffixWidth : " + suffixWidth);
}
string StripLengthWithSuffix(string input, int maxWidth = MAX_WIDTH)
{
int len = CalculateLengthOfText(input);
Debug.Log("input total length = " + len);
//截?cái)鄑ext的長度,如果總長度大于限制的最大長度,
//那么先根據(jù)最大長度減去后綴長度的值拿到字符串,在拼接上后綴
if (len > maxWidth)
{
return StripLength(input, maxWidth - suffixWidth) + suffix;
}else
{
return input;
}
}
//隨機(jī)生成個(gè)字符串
void Rand()
{
int min = 12;
int max = 16;
int num = (int)(Random.value * (max - min) + min);
Debug.Log("-------------------------\n num : " + num);
string s = "";
for (int j = 0; j < num; j++)
{
int len = seeds.Length;
int index = (int)(Random.value * (len));
s += seeds[index];
}
Debug.Log("s : " + s);
text.text = StripLengthWithSuffix(s);
Debug.Log("StripLength " + text.text);
}
/// <summary>
/// 根據(jù)maxWidth來截?cái)鄆nput拿到子字符串
/// </summary>
/// <param name="input"></param>
/// <param name="maxWidth"></param>
/// <returns></returns>
string StripLength(string input, int maxWidth = MAX_WIDTH)
{
int totalLength = 0;
Font myFont = text.font; //chatText is my Text component
myFont.RequestCharactersInTexture(input, text.fontSize, text.fontStyle);
CharacterInfo characterInfo = new CharacterInfo();
char[] arr = input.ToCharArray();
int i = 0;
foreach (char c in arr)
{
myFont.GetCharacterInfo(c, out characterInfo, text.fontSize);
int newLength = totalLength + characterInfo.advance;
if (newLength > maxWidth)
{
Debug.LogFormat("newLength {0}, totalLength {1}: ", newLength, totalLength);
if (Mathf.Abs(newLength - maxWidth) > Mathf.Abs(maxWidth - totalLength)){
break;
}else
{
totalLength = newLength;
i++;
break;
}
}
totalLength += characterInfo.advance;
i++;
}
Debug.LogFormat("totalLength {0} : ", totalLength);
return input.Substring(0, i);
}
/// <summary>
/// 計(jì)算字符串在指定text控件中的長度
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
int CalculateLengthOfText(string message)
{
int totalLength = 0;
Font myFont = text.font; //chatText is my Text component
myFont.RequestCharactersInTexture(message, text.fontSize, text.fontStyle);
CharacterInfo characterInfo = new CharacterInfo();
char[] arr = message.ToCharArray();
foreach (char c in arr)
{
myFont.GetCharacterInfo(c, out characterInfo, text.fontSize);
totalLength += characterInfo.advance;
}
return totalLength;
}
}
后續(xù)
這個(gè)效果基本達(dá)到要求,如果仔細(xì)看的話,并不能保證每個(gè)截取后的字符串一定是對齊的,這個(gè)也跟字符串有關(guān),畢竟字符串長度是離散的,貌似沒有辦法像word一樣在一行多一個(gè)文字的時(shí)候還可以擠一擠放下~
補(bǔ)充:Unity Text文字超框,末尾顯示‘...'省略號
// 超框顯示...
public static void SetTextWithEllipsis(this Text textComponent, string value)
{
var generator = new TextGenerator();
var rectTransform = textComponent.GetComponent<RectTransform>();
var settings = textComponent.GetGenerationSettings(rectTransform.rect.size);
generator.Populate(value, settings);
var characterCountVisible = generator.characterCountVisible;
var updatedText = value;
if (value.Length > characterCountVisible)
{
updatedText = value.Substring(0, characterCountVisible - 3);
updatedText += "…";
}
textComponent.text = updatedText;
}
調(diào)用方式:在給Text賦值的時(shí)候調(diào)用一次即可
text.SetTextWithEllipsis(titleDesc);
效果如下:

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
您可能感興趣的文章:- Unity3D運(yùn)行報(bào)DllNotFoundException錯(cuò)誤的解決方案
- unity avprovideo插件的使用詳解
- Unity3D啟動外部程序并傳遞參數(shù)的實(shí)現(xiàn)
- unity 如何獲取button文本的內(nèi)容
- unity 如何獲取Text組件里text內(nèi)容的長度
- unity 如何使用文件流讀取streamingassets下的資源
- unity 文件流讀取圖片與www讀取圖片的區(qū)別介紹
- Unity之繞軸進(jìn)行旋轉(zhuǎn)的操作
- 解決unity rotate旋轉(zhuǎn)物體 限制物體旋轉(zhuǎn)角度的大坑
- 詳解Unity安卓共享紋理
相關(guān)文章
-
C#使用Winform編寫一個(gè)圖片預(yù)覽器管理
這篇文章主要為大家詳細(xì)介紹了C#如何使用Winform編寫一個(gè)通用圖片預(yù)覽器管理,包含滾輪放大縮小,剪切,下一頁,方向變化等,需要的可以參考下 2024-02-02
-
C#使用CallContext緩存線程數(shù)據(jù)
這篇文章介紹了C#使用CallContext緩存線程數(shù)據(jù)的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下 2022-05-05
-
C#定時(shí)任務(wù)框架Quartz.NET介紹與用法
這篇文章介紹了C#定時(shí)任務(wù)框架Quartz.NET的用法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下 2022-02-02
-
通過C#編寫一個(gè)簡易的Windows截屏增強(qiáng)工具
在使用?Windows?系統(tǒng)的截屏快捷鍵?PrintScreen?截屏?xí)r,如果需要把截屏保存到文件,需要先粘貼到畫圖工具然后另存為文件。所以本文用C#編寫了一個(gè)簡易的Windows截屏增強(qiáng)工具,需要的可以參考一下 2022-05-05
-
ScriptControl控件執(zhí)行自定義VBS腳本示例分析
這篇文章主要介紹ScriptControl控件 msscript.ocx msscript.oca執(zhí)行自定義VBS腳本的示例代碼,需要的朋友可以參考下
2013-04-04
最新評論
前言
在unity的ugui中Text控件,有時(shí)我們會有各種各樣的需求,比如類似html中css的text-overflow屬性,希望一段文字如果不夠長就全顯示,如果特別長就截?cái)嗖⑶液竺婕由侠纭@種后綴。
好吧這樣的需求在ugui里貌似沒有現(xiàn)成的方法,如果有的話麻煩指點(diǎn)一下~
實(shí)現(xiàn)
大概的思路就是
- 首先要能判斷什么時(shí)候overflow
- 并且支持加上后綴
那么text控件本來是支持overflow然后直接截?cái)嗟?,但是比較暴力,直接砍斷,不能加后綴,并不滿足我們的需求。
然后如果簡單的通過字符個(gè)數(shù)截?cái)啵歉静恍?,如果根?jù)中英文字符來根據(jù)長度截?cái)啵@個(gè)我試過,然而字體并不一定是一個(gè)中文相當(dāng)于倆英文字符,于是乎如果有一大排lllll或者iii什么的,悲劇無以言表。
所以我們需要知道一段文字所對應(yīng)的渲染之后的長度。如果從text的preferwidth或者通過添加content size filter組件應(yīng)該也能完成類似任務(wù),不過我傾向于直接算好長度去填充。
這個(gè)功能核心代碼為
Font myFont = text.font; //chatText is my Text component myFont.RequestCharactersInTexture(message, text.fontSize, text.fontStyle); CharacterInfo characterInfo = new CharacterInfo(); char[] arr = message.ToCharArray(); foreach (char c in arr) { myFont.GetCharacterInfo(c, out characterInfo, text.fontSize); totalLength += characterInfo.advance; }
其中text為Text文本控件,RequestCharactersInTexture主要相當(dāng)于指定需要渲染哪些字符(然后根據(jù)CharacterInfo.characterInfo是可以拿到本次生成的去重后的字符集)。接下來通過myFont.GetCharacterInfo(c, out characterInfo, text.fontSize);分別去獲得每個(gè)字符的信息,然后characterInfo.advance就拿到了每個(gè)字符的渲染長度。
拿到每個(gè)字符長度之后那就簡單多了,計(jì)算一下需要截?cái)嗟淖址傞L度,如果大于限制長度,就除去后綴長度后,截取子字符串,然后再接上后綴。這個(gè)事情就搞定了。
全部如下,這個(gè)例子是需要一個(gè)text和一個(gè)button,點(diǎn)擊button,隨機(jī)生成文字在text上。
using UnityEngine; using System.Collections; using UnityEngine.UI; public class TextWidth : MonoBehaviour { public Text text; public Button button; const string suffix = "..."; const int MAX_WIDTH = 200; int suffixWidth = 0; string[] seeds = { "是都", "60°", "qの", "【】" , "d a", "as", "WW", "II", "fs", "as", "WW", "II", "fs" }; // Use this for initialization void Start () { Init(); button.onClick.AddListener(Rand); } void Init() { //計(jì)算后綴的長度 suffixWidth = CalculateLengthOfText(suffix); Debug.Log("suffixWidth : " + suffixWidth); } string StripLengthWithSuffix(string input, int maxWidth = MAX_WIDTH) { int len = CalculateLengthOfText(input); Debug.Log("input total length = " + len); //截?cái)鄑ext的長度,如果總長度大于限制的最大長度, //那么先根據(jù)最大長度減去后綴長度的值拿到字符串,在拼接上后綴 if (len > maxWidth) { return StripLength(input, maxWidth - suffixWidth) + suffix; }else { return input; } } //隨機(jī)生成個(gè)字符串 void Rand() { int min = 12; int max = 16; int num = (int)(Random.value * (max - min) + min); Debug.Log("-------------------------\n num : " + num); string s = ""; for (int j = 0; j < num; j++) { int len = seeds.Length; int index = (int)(Random.value * (len)); s += seeds[index]; } Debug.Log("s : " + s); text.text = StripLengthWithSuffix(s); Debug.Log("StripLength " + text.text); } /// <summary> /// 根據(jù)maxWidth來截?cái)鄆nput拿到子字符串 /// </summary> /// <param name="input"></param> /// <param name="maxWidth"></param> /// <returns></returns> string StripLength(string input, int maxWidth = MAX_WIDTH) { int totalLength = 0; Font myFont = text.font; //chatText is my Text component myFont.RequestCharactersInTexture(input, text.fontSize, text.fontStyle); CharacterInfo characterInfo = new CharacterInfo(); char[] arr = input.ToCharArray(); int i = 0; foreach (char c in arr) { myFont.GetCharacterInfo(c, out characterInfo, text.fontSize); int newLength = totalLength + characterInfo.advance; if (newLength > maxWidth) { Debug.LogFormat("newLength {0}, totalLength {1}: ", newLength, totalLength); if (Mathf.Abs(newLength - maxWidth) > Mathf.Abs(maxWidth - totalLength)){ break; }else { totalLength = newLength; i++; break; } } totalLength += characterInfo.advance; i++; } Debug.LogFormat("totalLength {0} : ", totalLength); return input.Substring(0, i); } /// <summary> /// 計(jì)算字符串在指定text控件中的長度 /// </summary> /// <param name="message"></param> /// <returns></returns> int CalculateLengthOfText(string message) { int totalLength = 0; Font myFont = text.font; //chatText is my Text component myFont.RequestCharactersInTexture(message, text.fontSize, text.fontStyle); CharacterInfo characterInfo = new CharacterInfo(); char[] arr = message.ToCharArray(); foreach (char c in arr) { myFont.GetCharacterInfo(c, out characterInfo, text.fontSize); totalLength += characterInfo.advance; } return totalLength; } }
后續(xù)
這個(gè)效果基本達(dá)到要求,如果仔細(xì)看的話,并不能保證每個(gè)截取后的字符串一定是對齊的,這個(gè)也跟字符串有關(guān),畢竟字符串長度是離散的,貌似沒有辦法像word一樣在一行多一個(gè)文字的時(shí)候還可以擠一擠放下~
補(bǔ)充:Unity Text文字超框,末尾顯示‘...'省略號
// 超框顯示... public static void SetTextWithEllipsis(this Text textComponent, string value) { var generator = new TextGenerator(); var rectTransform = textComponent.GetComponent<RectTransform>(); var settings = textComponent.GetGenerationSettings(rectTransform.rect.size); generator.Populate(value, settings); var characterCountVisible = generator.characterCountVisible; var updatedText = value; if (value.Length > characterCountVisible) { updatedText = value.Substring(0, characterCountVisible - 3); updatedText += "…"; } textComponent.text = updatedText; }
調(diào)用方式:在給Text賦值的時(shí)候調(diào)用一次即可
text.SetTextWithEllipsis(titleDesc);
效果如下:
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
- Unity3D運(yùn)行報(bào)DllNotFoundException錯(cuò)誤的解決方案
- unity avprovideo插件的使用詳解
- Unity3D啟動外部程序并傳遞參數(shù)的實(shí)現(xiàn)
- unity 如何獲取button文本的內(nèi)容
- unity 如何獲取Text組件里text內(nèi)容的長度
- unity 如何使用文件流讀取streamingassets下的資源
- unity 文件流讀取圖片與www讀取圖片的區(qū)別介紹
- Unity之繞軸進(jìn)行旋轉(zhuǎn)的操作
- 解決unity rotate旋轉(zhuǎn)物體 限制物體旋轉(zhuǎn)角度的大坑
- 詳解Unity安卓共享紋理
相關(guān)文章
C#使用Winform編寫一個(gè)圖片預(yù)覽器管理
這篇文章主要為大家詳細(xì)介紹了C#如何使用Winform編寫一個(gè)通用圖片預(yù)覽器管理,包含滾輪放大縮小,剪切,下一頁,方向變化等,需要的可以參考下2024-02-02C#使用CallContext緩存線程數(shù)據(jù)
這篇文章介紹了C#使用CallContext緩存線程數(shù)據(jù)的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05C#定時(shí)任務(wù)框架Quartz.NET介紹與用法
這篇文章介紹了C#定時(shí)任務(wù)框架Quartz.NET的用法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02通過C#編寫一個(gè)簡易的Windows截屏增強(qiáng)工具
在使用?Windows?系統(tǒng)的截屏快捷鍵?PrintScreen?截屏?xí)r,如果需要把截屏保存到文件,需要先粘貼到畫圖工具然后另存為文件。所以本文用C#編寫了一個(gè)簡易的Windows截屏增強(qiáng)工具,需要的可以參考一下2022-05-05ScriptControl控件執(zhí)行自定義VBS腳本示例分析
這篇文章主要介紹ScriptControl控件 msscript.ocx msscript.oca執(zhí)行自定義VBS腳本的示例代碼,需要的朋友可以參考下2013-04-04