【狂雲歌之unity_vr】unity裡獲取text中文字寬度並截斷省略
【狂雲歌之unity_vr】unity裡獲取text中文字寬度並截斷省略
前言
在unity的ugui中Text控制元件,有時我們會有各種各樣的需求,比如類似html中css的text-overflow屬性,希望一段文字如果不夠長就全顯示,如果特別長就截斷並且後面加上例如...這種字尾。
好吧這樣的需求在ugui裡貌似沒有現成的方法,如果有的話麻煩指點一下~
實現
大概的思路就是 - 首先要能判斷什麼時候overflow - 並且支援加上字尾
那麼text控制元件本來是支援overflow然後直接截斷的,但是比較暴力,直接砍斷,不能加字尾,並不滿足我們的需求。
然後如果簡單的通過字元個數截斷,那根本不行,如果根據中英文字元來根據長度截斷,這個我試過,然而字型並不一定是一箇中文相當於倆英文字元,於是乎如果有一大排lllll或者iii什麼的,悲劇無以言表。
所以我們需要知道一段文字所對應的渲染之後的長度。如果從text的preferwidth或者通過新增content size filter元件應該也能完成類似任務,不過我傾向於直接算好長度去填充。
這個功能核心程式碼為 ``` 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
主要相當於指定需要渲染哪些字元(然後根據CharacterInfo.characterInfo
是可以拿到本次生成的去重後的字符集)。接下來通過myFont.GetCharacterInfo(c, out characterInfo, text.fontSize);
分別去獲得每個字元的資訊,然後characterInfo.advance
就拿到了每個字元的渲染長度。
拿到每個字元長度之後那就簡單多了,計算一下需要截斷的字元總長度,如果大於限制長度,就除去字尾長度後,擷取子字串,然後再接上字尾。這個事情就搞定了。
效果如下:
全部如下,這個例子是需要一個text和一個button,點選button,隨機生成文字在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()
{
//計算字尾的長度
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);
//截斷text的長度,如果總長度大於限制的最大長度,
//那麼先根據最大長度減去字尾長度的值拿到字串,在拼接上字尾
if (len > maxWidth)
{
return StripLength(input, maxWidth - suffixWidth) + suffix;
}else
{
return input;
}
}
//隨機生成個字串
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>
/// 根據maxWidth來截斷input拿到子字串
/// </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>
/// 計算字串在指定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;
}
} ```
後續
這個效果基本達到要求,如果仔細看的話,並不能保證每個擷取後的字串一定是對齊的,這個也跟字串有關,畢竟字串長度是離散的,貌似沒有辦法像word一樣在一行多一個文字的時候還可以擠一擠放下~
VR開發或者unity相關交流可以郵件madcloudsong@qq.com 轉載請註明原文連結 http://blog.csdn.net/madcloudsong/article/details/54670045
相關文章
- Unity從圖片的位元組資料裡面獲取圖片的寬和高Unity
- 獲取各種螢幕高度寬度(工作)
- 根據id獲取元素的寬度的方法
- js 獲取可視介面的高度或寬度JS
- vue中檔案上傳阿里雲並獲取上傳進度Vue阿里
- 超過固定寬度(或行數)顯示…(或省略)
- Python 爬蟲獲取網易雲音樂歌手歌詞Python爬蟲
- JS,Jquery獲取各種螢幕的寬度和高度JSjQuery
- 透過Unity整合Huawei Game Service 並獲取玩家標識資訊UnityGAM
- 傑裡之.AC695 系列獲取藍芽的 ID3 歌詞和播放時間【篇】藍芽
- vue中文字框自動獲取焦點Vue
- Unity TMPro 中文字型集Unity
- 網易雲歌詞爬取(java)Java
- js/jq 獲取網頁寬高JS網頁
- win10系統如何獲取高解析度螢幕截圖Win10
- 正則匹配之零寬斷言
- C#判斷字串的顯示寬度C#字串
- 短視訊平臺原始碼,Android獲取螢幕的高度和寬度原始碼Android
- Unity Text Mesh 穿透問題Unity穿透
- SpringBoot 攔截器獲取 @RequestBody 引數Spring Boot
- react專案中不同寬度斷點處理React斷點
- 文字超出容器長度自動隱藏並且顯示省略號
- JQuery 獲取select被選中的value和textjQuery
- 可視區、標籤寬高的獲取
- Unity通過子物件獲取父物件例子Unity物件
- android獲取位置並上傳Android
- 獲取spring裡的beanSpringBean
- 獲取cookie裡面的值Cookie
- SpringBoot攔截器中獲取註解、攔截器中注入ServiceSpring Boot
- vue裡a標籤從後臺獲取連結並實現跳轉Vue
- app直播原始碼,flutter Text自動計算文字內容的寬度APP原始碼Flutter
- 百度地圖JavaScript API獲取使用者當前經緯度並獲取使用者當前詳細地理位置地圖JavaScriptAPI
- JAVA之反射學習2-獲取構造方法並使用Java反射構造方法
- Python爬取網易雲音樂歌單歌曲Python
- 最全的獲取元素寬高及位置的方法
- Flutter 中獲取螢幕以及 Widget 的寬高Flutter
- JS獲取元素寬高的兩種情況JS
- jQuery無法獲取隱藏元素(display:none)寬度(width)和高度(height)的新解決方案jQueryNone
- 如何獲取Cookie並使用Cookie侵入Cookie