Unity UGUI圖文混排原始碼(二)
圖文混排解決方案二:
2.自定義一個渲染元件,用來渲染圖片,後面我會將他放在Text文字下,這裡會用一個引數,就是上面的SpriteAsset檔案,具體程式碼如下
using UnityEngine; using UnityEngine.UI; using System.Collections; public class SpriteGraphic : MaskableGraphic { public SpriteAsset m_spriteAsset; public override Texture mainTexture { get { if (m_spriteAsset == null) return s_WhiteTexture; if (m_spriteAsset.texSource == null) return s_WhiteTexture; else return m_spriteAsset.texSource; } } #if UNITY_EDITOR //在編輯器下 protected override void OnValidate() { base.OnValidate(); //Debug.Log("Texture ID is " + this.texture.GetInstanceID()); } #endif protected override void OnRectTransformDimensionsChange() { // base.OnRectTransformDimensionsChange(); } /// <summary> /// 繪製後 需要更新材質 /// </summary> public new void UpdateMaterial() { base.UpdateMaterial(); } }
3.自定義一個指令碼用來繼承Text,這裡就是一個較為核心的程式碼,裡面寫了較為詳細的註釋
using UnityEngine; using UnityEngine.UI; using System.Collections.Generic; using System.Text.RegularExpressions; public class InlieText : Text { /// <summary> /// 用正則取標籤屬性 名稱-大小-寬度比例 /// </summary> private static readonly Regex m_spriteTagRegex = new Regex(@"<quad name=(.+?) size=(\d*\.?\d+%?) width=(\d*\.?\d+%?) />", RegexOptions.Singleline); /// <summary> /// 需要渲染的圖片資訊列表 /// </summary> private List<InlineSpriteInfor> listSprite; /// <summary> /// 圖片資源 /// </summary> private SpriteAsset m_spriteAsset; /// <summary> /// 標籤的資訊列表 /// </summary> private List<SpriteTagInfor> listTagInfor; /// <summary> /// 圖片渲染元件 /// </summary> private SpriteGraphic m_spriteGraphic; /// <summary> /// CanvasRenderer /// </summary> private CanvasRenderer m_spriteCanvasRenderer; /// <summary> /// 初始化 /// </summary> protected override void OnEnable() { base.OnEnable(); if (m_spriteGraphic == null) m_spriteGraphic = GetComponentInChildren<SpriteGraphic>(); if (m_spriteCanvasRenderer == null) m_spriteCanvasRenderer = m_spriteGraphic.GetComponentInChildren<CanvasRenderer>(); m_spriteAsset = m_spriteGraphic.m_spriteAsset; } /// <summary> /// 在設定頂點時呼叫 /// </summary> public override void SetVerticesDirty() { base.SetVerticesDirty(); //解析標籤屬性 listTagInfor = new List<SpriteTagInfor>(); foreach (Match match in m_spriteTagRegex.Matches(text)) { SpriteTagInfor tempSpriteTag = new SpriteTagInfor(); tempSpriteTag.name = match.Groups[1].Value; tempSpriteTag.index = match.Index; tempSpriteTag.size = new Vector2(float.Parse(match.Groups[2].Value)*float.Parse(match.Groups[3].Value), float.Parse(match.Groups[2].Value)); listTagInfor.Add(tempSpriteTag); } } /// <summary> /// 繪製模型 /// </summary> /// <param name="toFill"></param> protected override void OnPopulateMesh(VertexHelper toFill) { base.OnPopulateMesh(toFill); //獲取所有的UIVertex,繪製一個字元對應6個UIVertex,繪製順序為012 203 List<UIVertex> listUIVertex = new List<UIVertex>(); toFill.GetUIVertexStream(listUIVertex); //通過標籤資訊來設定需要繪製的圖片的資訊 listSprite = new List<InlineSpriteInfor>(); for (int i = 0; i < listTagInfor.Count; i++) { //UGUIText不支援<quad/>標籤,表現為亂碼,我這裡將他的uv全設定為0,清除亂碼 for (int m = listTagInfor[i].index*6; m < listTagInfor[i].index*6 + 6; m++) { UIVertex tempVertex = listUIVertex[m]; tempVertex.uv0 = Vector2.zero; listUIVertex[m] = tempVertex; } InlineSpriteInfor tempSprite = new InlineSpriteInfor(); //如果圖片在第一個位置,則計算他的位置為文字的初始點位置 //否,則返回上一個字元的第三個UIVertex的position,這是根據他的頂點的繪製順序所獲得的 if (listTagInfor[i].index == 0) { Vector2 anchorPivot = GetTextAnchorPivot(alignment); Vector2 rectSize = rectTransform.sizeDelta; tempSprite.textpos = -rectSize / 2.0f + new Vector2(rectSize.x * anchorPivot.x,rectSize.y*anchorPivot.y- listTagInfor[i].size.y); } else tempSprite.textpos = listUIVertex[listTagInfor[i].index * 6 - 4].position; //設定圖片的位置 tempSprite.vertices = new Vector3[4]; tempSprite.vertices[0] = new Vector3(0, 0, 0) + tempSprite.textpos; tempSprite.vertices[1] = new Vector3(listTagInfor[i].size.x, listTagInfor[i].size.y, 0) + tempSprite.textpos; tempSprite.vertices[2] = new Vector3(listTagInfor[i].size.x, 0, 0) + tempSprite.textpos; tempSprite.vertices[3] = new Vector3(0, listTagInfor[i].size.y, 0) + tempSprite.textpos; //計算其uv Rect spriteRect = m_spriteAsset.listSpriteInfor[0].rect; for (int j = 0; j < m_spriteAsset.listSpriteInfor.Count; j++) { //通過標籤的名稱去索引spriteAsset裡所對應的sprite的名稱 if (listTagInfor[i].name == m_spriteAsset.listSpriteInfor[j].name) spriteRect = m_spriteAsset.listSpriteInfor[j].rect; } Vector2 texSize = new Vector2(m_spriteAsset.texSource.width, m_spriteAsset.texSource.height); tempSprite.uv = new Vector2[4]; tempSprite.uv[0] = new Vector2(spriteRect.x / texSize.x, spriteRect.y / texSize.y); tempSprite.uv[1] = new Vector2((spriteRect.x + spriteRect.width) / texSize.x, (spriteRect.y + spriteRect.height) / texSize.y); tempSprite.uv[2] = new Vector2((spriteRect.x + spriteRect.width) / texSize.x, spriteRect.y / texSize.y); tempSprite.uv[3] = new Vector2(spriteRect.x / texSize.x, (spriteRect.y + spriteRect.height) / texSize.y); //宣告三角頂點所需要的陣列 tempSprite.triangles = new int[6]; listSprite.Add(tempSprite); } //清除<quad />標籤的亂碼 重新繪製 toFill.Clear(); toFill.AddUIVertexTriangleStream(listUIVertex); DrawSprite(); } /// <summary> /// 繪製圖片 /// </summary> void DrawSprite() { Mesh m_spriteMesh = new Mesh(); List<Vector3> tempVertices = new List<Vector3>(); List<Vector2> tempUv = new List<Vector2>(); List<int> tempTriangles = new List<int>(); for (int i = 0; i < listSprite.Count; i++) { for (int j = 0; j < listSprite[i].vertices.Length; j++) { tempVertices.Add(listSprite[i].vertices[j]); } for (int j = 0; j < listSprite[i].uv.Length; j++) { tempUv.Add(listSprite[i].uv[j]); } for (int j = 0; j < listSprite[i].triangles.Length; j++) { tempTriangles.Add(listSprite[i].triangles[j]); } } //計算頂點繪製順序 for (int i = 0; i < tempTriangles.Count; i++) { if (i % 6 == 0) { int num = i / 6; tempTriangles[i] = 0 + 4 * num; tempTriangles[i + 1] = 1 + 4 * num; tempTriangles[i + 2] = 2 + 4 * num; tempTriangles[i + 3] = 1 + 4 * num; tempTriangles[i + 4] = 0 + 4 * num; tempTriangles[i + 5] = 3 + 4 * num; } } m_spriteMesh.vertices = tempVertices.ToArray(); m_spriteMesh.uv = tempUv.ToArray(); m_spriteMesh.triangles = tempTriangles.ToArray(); if (m_spriteMesh == null) return; m_spriteCanvasRenderer.SetMesh(m_spriteMesh); m_spriteGraphic.UpdateMaterial(); } } [System.Serializable] public class SpriteTagInfor { /// <summary> /// sprite名稱 /// </summary> public string name; /// <summary> /// 對應的字元索引 /// </summary> public int index; /// <summary> /// 大小 /// </summary> public Vector2 size; } [System.Serializable] public class InlineSpriteInfor { // 文字的最後的位置 public Vector3 textpos; // 4 頂點 public Vector3[] vertices; //4 uv public Vector2[] uv; //6 三角頂點順序 public int[] triangles; }
4.開始測試效果,建立一個InlieText元件,並在其元件下,新增一個SpriteGraphic元件,輸入文字加標籤測試
InlieTex元件:
SpriteGraphic元件:
文字測試:
5.做了一個聊天測試:
6.同時在測試的時候就發現了些許bug,這裡並不想寫出來,有興趣的可以一起修改討論。
工程使用的unity版本為unity的版本為:5.3.1f1
相關推薦
Unity UGUI圖文混排原始碼(二)
圖文混排解決方案二:2.自定義一個渲染元件,用來渲染圖片,後面我會將他放在Text文字下,這裡會用一個引數,就是上面的SpriteAsset檔案,具體程式碼如下using UnityEngine; using UnityEngine.UI; using System.Coll
Unity UGUI圖文混排原始碼(三) -- 動態表情
這裡是根據圖文混排原始碼(二)進一步修改的,其他連結也不貼了,就貼一個連結就好了,第一次看這文章的同學可以先去看看其他幾篇文章1.首先來一個好訊息,在最新版本的圖文混排中,終於搞定了<quad&g
Unity UGUI圖文混排(七) -- 下劃線
之前更新超連結的時候,忘了搭配實現一個下劃線的功能,這篇文章就是來補上這一個功能,時間有點長,一方面沒有很好的思路,一方面也沒多少時間。先在網上收集了一下下劃線的實現操作,一種是在文字下再建立一個文字用來輸入下劃線,一種是在文字下再建立一個圖片用來繪製下劃線,這兩種方式都相當
[UGUI]圖文混排(二):下劃線
otherwise ret align protected result pve amp HA fse UGUI源碼: https://bitbucket.org/Unity-Technologies/ui/downloads/?tab=tags 首先下載一份UGUI源
Unity瑣碎(3) UGUI 圖文混排解決方案和優化
http://www.cnblogs.com/zsb517/p/6667050.html 感覺使用Unity之後總能看到各種各樣解決混排的方案,只能說明Unity不夠體恤下情啊。這篇文章主要講一下個人在使用過程中方案選擇和優化過程,已做記錄。順便提下,開源很多意味著坑,
[UGUI]圖文混排(三):插入圖片
img bsp static readonly 圖片標簽 pre esc 分享圖片 gist 參考鏈接: http://www.cnblogs.com/leoin2012/p/7162099.html 1.用空格替換圖片標簽 a.選擇空格符 換行空格:Space鍵輸出的
[UGUI]圖文混排(三):資源管理
圖片 dal cti sharp ons set creat ces turn 1.圖文混排中的資源,主要是圖片。 2.所謂的資源管理,可以分為資源對象池和資源加載這兩部分。這裏是為圖文混排單獨做一套資源管理,當然也可以改為調用項目中的資源管理。 RichTextRes
[UGUI]圖文混排(五):添加下劃線
字符 方法 ugui fff info cal 去掉 分享圖片 src 0.下劃線標簽
UGUI圖文混排外掛Text Mesh Pro
Text Mesh Pro外掛下載地址: https://github.com/UnityTechnologies/Test_ShaderGraphBlog 外掛線上文件: http://digitalnativestudios.com/textmeshpro/docs/ 使用效
unity NGUI圖文混排
遊戲中需要製作聊天功能,很可能會使用到圖文混排,這裡介紹一下基於NGUI的一種做法。 步驟1:工程中得先匯入一箇中文字型庫,ttf格式,如果是ttc格式的,強行改成ttf格式即可。如果你已經匯入過了,忽略此步: 步驟2:開啟NGUI的Font Maker,製作一個字型
靜態頁面制作:8HTML浮動騰挪概念(鋪墊二:圖文混排)
net 們的 屬於 元素 含義 網頁 我們 紅色 背景 .paragraph { width: 80%; margin: 50px auto; color: #666; font-size: 20px; text-align: left; line-height: 200%
基於UGUI的圖文混排——第一部分
UGUI的Text渲染 Text的繼承關係:Text -> MaskableGraphic -> Graphic 然後我們 F12 看看 Graphic 被公佈出來可重寫或者可呼叫有哪些
【Unity3D遊戲開發】基於NGUI的表情圖文混排解決方案 (二二)
使用unity3d也有兩年時間了,最近比較閒,有功夫梳理一下去年一年來學到以及用到的知識,分享給大家,順便方便自己查閱。如有錯誤以及不當的地方,歡迎各位指正。謝謝。 去年五月份的時候,剛加入專案不久,老大交給我一個關於聊天系統任務,期初覺得應該很容易,但是看了文
Unity3D 基於UGUI的圖文混排元件
起因:在使用UGUI的時候,在網上找了好久也沒找到合適的圖文混排元件,但是有看到一篇文章給了我思路。甩個連結:點選開啟連結 思路:是通過繼承Text元件,然後在Mesh生成的函式裡做手腳。但是那篇文章好像有些bug,而且UGUI的程式碼也是開源的,所以就自己動手了。就是把
Unity外掛之NGUI學習(5)—— 建立Label圖文混排及文字點選
建立一個新的Scene,並按 Unity外掛之NGUI學習(2)建立UI Root。 準備工作,製作Font,現在Project視窗建立一個Font資料夾,然後從系統自帶字型資料夾中選擇自己需要的字型,我選擇了黑體,然後拖到Font資料夾中去。選擇剛匯入的字型。 Font
IOS開發UI篇--一個支持圖文混排的ActionSheet
log one 簡單介紹 button action 曾經 hot uitable ios 一、簡單介紹 UIActionSheet是IOS提供給我們開發人員的底部彈出菜單控件。一般用於菜單選擇、操作確認、刪除確認等功能。IOS官方提供的下面方式對UI
圖文混排-------專輯詳情
cnblogs 微信 集成 服務 字符 -c containe git view ---恢復內容開始--- 最近,需求要求做一個專輯詳情的圖文混排,整個界面大概分為4部分: 1.頂部banner和音頻控制區 2.中間圖文混排區,文字解析CSS代碼,圖片做多種跳轉
Android圖文混排-實現EditText圖文混合插入上傳
origin uri keyword src llb fail ren -a amp 前段時間做了一個Android會議管理系統,項目需求涉及到EditText的圖文混排,如圖: 在上圖的”會議詳情”中。須要支持文本和圖片的混合插入,下圖演示輸入的
Button實現圖文混排
actor stat 實現圖 1.0 eve onf demo mat ont Button實現圖文混排 一、簡介 本文介紹兩種圖文混排方式 1、android:drawableTop="@drawable/star"實現文字上有圖片 當然有上下左右等等 2、Spannab
利用NSAttributedString實現圖文混排
nes -s union ref and 代理方法 tag erl efault UILabel 和 UITextView 都能添加 NSAttributedString 屬性字符串,通過這一點,可以實現帶有屬性的文字和文字內包含圖片的文本內容展示. 效果如下: 1-