网站备案才能使用,重庆市建设工程造价信息2020,南昌哪里可以做企业网站,营销型的物流网站模板unity版本#xff1a;2021.3.6f1 局限性#xff1a; 1.测试发现不能使用 size 富文本标签, 2.同一文本不能设置不同颜色的超链接文本 其它#xff1a;代码中注释掉使用innerTextColor的地方#xff0c;可以使用富文本设置超链接颜色#xff0c; 但是下划线是文本本身颜色 …unity版本2021.3.6f1 局限性 1.测试发现不能使用 size 富文本标签, 2.同一文本不能设置不同颜色的超链接文本 其它代码中注释掉使用innerTextColor的地方可以使用富文本设置超链接颜色 但是下划线是文本本身颜色
项目需要用到该功能 搜索和参考了很多文章要么不支持富文本要不没有下划线要么是错误的修修改改后满足我的需求代码如下
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;namespace MyTool.Tools
{/// summary/// 文本控件支持超链接、下划线/// /summarypublic class HyperlinkText : Text, IPointerClickHandler{public Actionstring onHyperlinkClick;/// 超链接信息类private class HyperlinkInfo{public int startIndex;public int endIndex;public string name;public readonly ListRect boxes new ListRect();public Listint linefeedIndexList new Listint();}/// 解析完最终的文本private string m_OutputText;/// 超链接信息列表private readonly ListHyperlinkInfo m_HrefInfos new ListHyperlinkInfo();/// 文本构造器protected StringBuilder s_TextBuilder new StringBuilder();[Tooltip(超链接文本颜色)][SerializeField] private Color32 innerTextColor new Color32(36, 64, 180, 255);/// 超链接正则private static readonly Regex s_HrefRegex new Regex(href([^\n\s])(.*?)(/href), RegexOptions.Singleline);// ugui富文本标签// 格式1b/b i/iprivate static readonly string[] _uguiSymbols1 { b, i };// 格式2color#ffffff/color colorred/colorprivate static readonly string[] _uguiSymbols2 { color, size };public string GetHyperlinkInfo { get { return text; } }public override void SetVerticesDirty(){base.SetVerticesDirty();text GetHyperlinkInfo;m_OutputText GetOutputText(text);}protected override void OnPopulateMesh(VertexHelper toFill){var orignText m_Text;m_Text m_OutputText;base.OnPopulateMesh(toFill);m_Text orignText;UIVertex vert new UIVertex();// 处理超链接包围框foreach (var hrefInfo in m_HrefInfos){hrefInfo.boxes.Clear();hrefInfo.linefeedIndexList.Clear();if (hrefInfo.startIndex toFill.currentVertCount)continue;// 将超链接里面的文本顶点索引坐标加入到包围框toFill.PopulateUIVertex(ref vert, hrefInfo.startIndex);var pos vert.position;var bounds new Bounds(pos, Vector3.zero);hrefInfo.linefeedIndexList.Add(hrefInfo.startIndex);for (int i hrefInfo.startIndex, m hrefInfo.endIndex; i m; i){if (i toFill.currentVertCount)break;toFill.PopulateUIVertex(ref vert, i);vert.color innerTextColor;toFill.SetUIVertex(vert, i);pos vert.position;bool needEncapsulate true;if (i 4 (i - hrefInfo.startIndex) % 4 0){UIVertex lastV new UIVertex();toFill.PopulateUIVertex(ref lastV, i - 4);var lastPos lastV.position;if (pos.x lastPos.x pos.y lastPos.y) // 换行重新添加包围框{hrefInfo.boxes.Add(new Rect(bounds.min, bounds.size));hrefInfo.linefeedIndexList.Add(i);bounds new Bounds(pos, Vector3.zero);needEncapsulate false;}}if (needEncapsulate){bounds.Encapsulate(pos); // 扩展包围框}}hrefInfo.boxes.Add(new Rect(bounds.min, bounds.size));}//一个字一个字的划 效率差 而且字与字之间容易有接缝DrawUnderLine(toFill);}private void DrawUnderLine(VertexHelper vh){UIVertex vert new UIVertex();ListVector3 startPosList new ListVector3();ListVector3 endPosList new ListVector3();foreach (var hrefInfo in m_HrefInfos){if (hrefInfo.startIndex vh.currentVertCount) continue;float minY float.MaxValue;for (int i hrefInfo.startIndex, m hrefInfo.endIndex; i m; i 4){if (i vh.currentVertCount)break;if (hrefInfo.linefeedIndexList.Contains(i)){for (int j 0; j startPosList.Count; j){MeshUnderLine(vh, new Vector2(startPosList[j].x, minY), new Vector2(endPosList[j].x, minY));}startPosList.Clear();endPosList.Clear();}vh.PopulateUIVertex(ref vert, i 3);startPosList.Add(vert.position);vh.PopulateUIVertex(ref vert, i 2);endPosList.Add(vert.position);if (vert.position.y minY){minY vert.position.y;}}for (int j 0; j startPosList.Count; j){MeshUnderLine(vh, new Vector2(startPosList[j].x, minY), new Vector2(endPosList[j].x, minY));}startPosList.Clear();endPosList.Clear();}}private void MeshUnderLine(VertexHelper vh, Vector2 startPos, Vector2 endPos){Vector2 extents rectTransform.rect.size;var setting GetGenerationSettings(extents);TextGenerator underlineText new TextGenerator();underlineText.Populate(—, setting);IListUIVertex lineVer underlineText.verts;/*new UIVertex[4];*///_的的顶点数组Vector3[] pos new Vector3[4];pos[0] startPos new Vector2(-1f, 0);pos[3] startPos new Vector2(-1f, 4f);pos[2] endPos new Vector2(1f, 4f);pos[1] endPos new Vector2(1f, 0);UIVertex[] tempVerts new UIVertex[4];for (int i 0; i 4; i){tempVerts[i] lineVer[i];tempVerts[i].color innerTextColor;tempVerts[i].position pos[i];}vh.AddUIVertexQuad(tempVerts);}/// summary/// 获取超链接解析后的最后输出文本/// /summary/// returns/returnsprotected virtual string GetOutputText(string outputText){s_TextBuilder.Length 0;m_HrefInfos.Clear();var indexText 0;int count 0;foreach (Match match in s_HrefRegex.Matches(outputText)){string appendStr outputText.Substring(indexText, match.Index - indexText);s_TextBuilder.Append(appendStr);//空格和回车没有顶点渲染所以要去掉count appendStr.Length - appendStr.Replace( , ).Replace(\n, ).Length;//去掉富文本标签的长度for (int i 0; i _uguiSymbols1.Length; i){count appendStr.Length - appendStr.Replace(${_uguiSymbols1[i]}, ).Replace($/{_uguiSymbols1[i]}, ).Length;}for (int i 0; i _uguiSymbols2.Length; i){string pattern ${_uguiSymbols2[i]}(.*?);count appendStr.Length - Regex.Replace(appendStr, pattern, ).Length;count appendStr.Length - appendStr.Replace($/{_uguiSymbols2[i]}, ).Length;}int startIndex (s_TextBuilder.Length - count) * 4;var group match.Groups[1];var hrefInfo new HyperlinkInfo{startIndex startIndex, // 超链接里的文本起始顶点索引endIndex startIndex (match.Groups[2].Length * 4),name group.Value};m_HrefInfos.Add(hrefInfo);s_TextBuilder.Append(match.Groups[2].Value);indexText match.Index match.Length;}s_TextBuilder.Append(outputText.Substring(indexText, outputText.Length - indexText));return s_TextBuilder.ToString();}/// summary/// 点击事件检测是否点击到超链接文本/// /summary/// param nameeventData/parampublic void OnPointerClick(PointerEventData eventData){Vector2 lp Vector2.zero;RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out lp);foreach (var hrefInfo in m_HrefInfos){var boxes hrefInfo.boxes;for (var i 0; i boxes.Count; i){if (boxes[i].Contains(lp)){if (onHyperlinkClick ! null)onHyperlinkClick.Invoke(hrefInfo.name);return;}}}}#if UNITY_EDITOR//需延迟调用该方法private void AddVisibleBound(){int index 0;foreach (var hrefInfo in m_HrefInfos){Color color new Color(UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f), 0.2f);index;foreach (Rect rect in hrefInfo.boxes){GameObject gameObject new GameObject();gameObject.name string.Format(GOBoundBox[{0}], hrefInfo.name);gameObject.transform.SetParent(this.gameObject.transform, false);RectTransform rectTransform gameObject.AddComponentRectTransform();rectTransform.sizeDelta rect.size;rectTransform.localPosition new Vector3(rect.position.x rect.size.x / 2, rect.position.y rect.size.y / 2, 0);Image image gameObject.AddComponentImage();image.color color;image.raycastTarget false;}}}
#endif}
}编辑器扩展 代码
using UnityEditor;
using UnityEngine;namespace MyTool
{[CanEditMultipleObjects][CustomEditor(typeof(Tools.HyperlinkText), true)]public class HyperlinkTextEditor : UnityEditor.UI.TextEditor{SerializedProperty _innerTextColor;protected override void OnEnable(){base.OnEnable();_innerTextColor serializedObject.FindProperty(innerTextColor);}public override void OnInspectorGUI(){base.OnInspectorGUI();serializedObject.Update();EditorGUILayout.PropertyField(_innerTextColor, new GUIContent(Inner Text Color));serializedObject.ApplyModifiedProperties();if (GUI.changed){EditorUtility.SetDirty(target);}}}
}Demo代码
using MyTool.Tools;
using System.Collections;
using UnityEngine;public class Demo2 : MonoBehaviour
{public HyperlinkText text;// Start is called before the first frame updatevoid Start(){//设置点击回调text.onHyperlinkClick OnClickText;StartCoroutine(AddVisibleBound());}IEnumerator AddVisibleBound(){yield return null;text.AddVisibleBound();}void OnClickText(string s){if (s 第一段第一句){Debug.Log($111---{s});}else if (s 第二段第一句){Debug.Log($222---{s});}else{Debug.Log($333---{s});}}
}
demo测试文本
color#ffffffbsize36背着手踱着。/size/b/colorcolorffffffhref第一段第一句路上只我一个人/href/colorsize45这一片天地好像是我的;我也像超出了平常旳自己到了另一世界里。我爱热闹也爱冷静;爱群居也爱独处。像今晚上一个人在这苍茫旳月下什么都可以想什么都可以不想便觉是个自由的人。/size白天里一定要做的事一定要说的话现在都可不理。bcolorgreen这是独处的妙处我且受用这无边的荷香月色好了。/color/bhref第二段第一句曲曲折折的荷塘上面/href弥望旳是田田的叶子。叶子出水很高像亭亭旳舞女旳裙。层层的叶子中间零星地点缀着些白花有袅娜(niǎo,nuó)地开着旳有羞涩地打着朵儿旳;正如一粒粒的明珠又如碧天里的星星又如刚出浴的美人。微风过处送来缕缕清香仿佛远处高楼上渺茫的歌声似的。这时候叶子与花也有一丝的颤动像闪电般霎时传过荷塘的那边去了。叶子本是肩并肩密密地挨着这便宛然有了一道凝碧的波痕。叶子底下是脉脉(mò)的流水遮住了不能见一些颜色;而叶子却更见风致了。size60月光如流水一般静静地泻在这一片叶子和花上。薄薄的青雾浮起在荷塘里。叶子和花仿佛在牛乳中洗过一样;又像笼着轻纱的梦。虽然是满月天上却有一层淡淡的云所以不能朗照;但我以为/size这恰是到了好处——酣眠固不可少小睡也别有风味的。月光是隔了树照过来的高处丛生的灌木落下参差的斑驳的黑影峭楞楞如鬼一般;弯弯的杨柳的稀疏的倩影却又像是画在荷叶上。塘中的月色并不均匀;但光与影有着和谐的旋律href第三段如梵婀(ē)玲(英语violin小提琴的译音)上奏着的名曲/href。colorredi荷塘的四面远远近近高高低低都是树而杨柳最多。/i/colorhref第四段这些树将一片荷塘重重围住/href;只在小路一旁漏着几段空隙像是特为月光留下的。树色一例是阴阴的乍看像一团烟雾;但杨柳的丰姿便在烟雾里也辨得出。树梢上隐隐约约的是一带远山只有些大意罢了。树缝里也漏着一两点路灯光没精打采的是渴睡人的眼。这时候最热闹的要数树上的蝉声与水里的蛙声;但热闹是它们的我什么也没有。ui 效果