在项目开发中,和ui界面打交道是必不可少的,但是最近发现ugui提供的text组件,在很多情况下不能满足美术的需求,这就对text组件进行扩展编辑,使其尽可能满足项目的需求,这里主要实现字间距、字体颜色、字体阴影、字体描边、字体根据需求自动选择字体和颜色字号等功能。

一、关于字间距的实现:

 public void PopulateMesh(VertexHelper toFill){if (UseTextSpacing){if (toFill.currentVertCount == 0){return;}List<UIVertex> vertexs = new List<UIVertex>();toFill.GetUIVertexStream(vertexs);int indexCount = toFill.currentIndexCount;UIVertex vt;for (int i = 6; i < indexCount; i++){//第一个字不用改变位置vt = vertexs[i];vt.position += new Vector3(m_TextSpacing * (i / 6), 0, 0);vertexs[i] = vt;//以下注意点与索引的对应关系if (i % 6 <= 2){toFill.SetUIVertex(vt, (i / 6) * 4 + i % 6);}if (i % 6 == 4){toFill.SetUIVertex(vt, (i / 6) * 4 + i % 6 - 1);}}}}

二、关于字体颜色的调整:

 public void PopulateMesh(VertexHelper toFill, RectTransform rectTransform, Color color){if (UseVertexColor){Vector2 min = rectTransform.pivot;min.Scale(-rectTransform.rect.size);Vector2 max = rectTransform.rect.size + min;int len = toFill.currentVertCount;for (int i = 0; i < len; i++){UIVertex v = new UIVertex();toFill.PopulateUIVertex(ref v, i);v.color = RemapColor(min, max, color, v.position);toFill.SetUIVertex(v, i);}}}private Color RemapColor(Vector2 min, Vector2 max, Color color, Vector2 pos){float x01 = max.x == min.x ? 0f : Mathf.Clamp01((pos.x - min.x) / (max.x - min.x));float y01 = max.y == min.y ? 0f : Mathf.Clamp01((pos.y - min.y) / (max.y - min.y));x01 -= VertexColorOffset.x * (VertexColorOffset.x > 0f ? x01 : (1f - x01));y01 -= VertexColorOffset.y * (VertexColorOffset.y > 0f ? y01 : (1f - y01));Color newColor = Color.Lerp(Color.Lerp(VertexBottomLeft, VertexBottomRight, x01),Color.Lerp(VertexTopLeft, VertexTopRight, x01),y01);switch (VertexColorFilter){default:     case ColorFilterType.Additive:return color + newColor;        case ColorFilterType.OverLap:float a = Mathf.Max(newColor.a, color.a);newColor = Color.Lerp(color, newColor, newColor.a);newColor.a = a;return newColor;}}

实现效果:

三、实现字体阴影:

 public Vector2 effectDistance{get { return m_EffectDistance; }set{if (value.x > kMaxEffectDistance)value.x = kMaxEffectDistance;if (value.x < -kMaxEffectDistance)value.x = -kMaxEffectDistance;if (value.y > kMaxEffectDistance)value.y = kMaxEffectDistance;if (value.y < -kMaxEffectDistance)value.y = -kMaxEffectDistance;if (m_EffectDistance == value)return;m_EffectDistance = value;}}protected void ApplyShadow(List<UIVertex> verts, Vector2 min, Vector2 max, Color32 color, float x, float y){UIVertex vt;int start = 0, end = verts.Count;var neededCapacity = verts.Count + end - start;if (verts.Capacity < neededCapacity)verts.Capacity = neededCapacity;for (int i = start; i < end; ++i){vt = verts[i];verts.Add(vt);Vector3 v = vt.position;v.x += x;v.y += y;vt.position = v;vt.color = RemapColor(min, max, color, v);verts[i] = vt;}}private Color RemapColor(Vector2 min, Vector2 max, Color color, Vector2 pos){float x01 = max.x == min.x ? 0f : Mathf.Clamp01((pos.x - min.x) / (max.x - min.x));float y01 = max.y == min.y ? 0f : Mathf.Clamp01((pos.y - min.y) / (max.y - min.y));x01 -= m_VertexColorOffset.x * (m_VertexColorOffset.x > 0f ? x01 : (1f - x01));y01 -= m_VertexColorOffset.y * (m_VertexColorOffset.y > 0f ? y01 : (1f - y01));Color newColor = Color.Lerp(Color.Lerp(VertexBottomLeft, VertexBottomRight, x01),Color.Lerp(VertexTopLeft, VertexTopRight, x01),y01);//使用全新颜色 不继承原有的return newColor;//return color * newColor;}public void PopulateMesh(VertexHelper vh, RectTransform rectTransform, Color color){if (UseShadow){Vector2 min = rectTransform.pivot;min.Scale(-rectTransform.rect.size);Vector2 max = rectTransform.rect.size + min;List<UIVertex> output = new List<UIVertex>();vh.GetUIVertexStream(output);ApplyShadow(output, min, max, color, effectDistance.x, effectDistance.y);vh.Clear();vh.AddUIVertexTriangleStream(output);}}

四、字体描边的实现

public Vector2 EffectDistance{get { return m_EffectDistance; }set{if (value.x > kMaxEffectDistance)value.x = kMaxEffectDistance;if (value.x < -kMaxEffectDistance)value.x = -kMaxEffectDistance;if (value.y > kMaxEffectDistance)value.y = kMaxEffectDistance;if (value.y < -kMaxEffectDistance)value.y = -kMaxEffectDistance;if (m_EffectDistance == value)return;m_EffectDistance = value;}}protected void ApplyShadowZeroAlloc(List<UIVertex> verts, Color32 color, int start, int end, float x, float y){UIVertex vt;var neededCapacity = verts.Count + end - start;if (verts.Capacity < neededCapacity)verts.Capacity = neededCapacity;for (int i = start; i < end; ++i){vt = verts[i];verts.Add(vt);Vector3 v = vt.position;v.x += x;v.y += y;vt.position = v;var newColor = color;newColor.a = (byte)((newColor.a * verts[i].color.a) / 255);vt.color = newColor;verts[i] = vt;}}public void PopulateMesh(VertexHelper vh){if (UseOutline){List<UIVertex> verts = new List<UIVertex>();vh.GetUIVertexStream(verts);var neededCpacity = verts.Count * 5;if (verts.Capacity < neededCpacity)verts.Capacity = neededCpacity;var start = 0;var end = verts.Count;ApplyShadowZeroAlloc(verts, EffectColor, start, verts.Count, EffectDistance.x, EffectDistance.y);start = end;end = verts.Count;ApplyShadowZeroAlloc(verts, EffectColor, start, verts.Count, EffectDistance.x, -EffectDistance.y);start = end;end = verts.Count;ApplyShadowZeroAlloc(verts, EffectColor, start, verts.Count, -EffectDistance.x, EffectDistance.y);start = end;end = verts.Count;ApplyShadowZeroAlloc(verts, EffectColor, start, verts.Count, -EffectDistance.x, -EffectDistance.y);vh.Clear();vh.AddUIVertexTriangleStream(verts);}}

五、本地默认颜色和字体的修改,主要实现直接调整为指定文字格式和颜色的功能,例如游戏中有tip、标题、二级弹框等字体,可以直接设置为指定的格式

  public void UpdateText(Text target){txt_Target = target;if (m_UseLocalization == false)return;m_TextStyle = (TextStyle)(int)m_TextStyleCN;//通过类型选择字体和颜色var color_ = Color.black;TextStyleFont fontStyle = new TextStyleFont(){font = Resources.Load<Font>(""),fontSize = 20};switch (m_TextStyle){case TextStyle.SystemTitle:color_ = Color.blue;txt_Target.font = Resources.Load<Font>("Font/FZZDHJW");txt_Target.fontSize = 35;break;case TextStyle.SecondTipTitle:color_ = Color.yellow;txt_Target.font = Resources.Load<Font>("Font/FZZDHJW");txt_Target.fontSize = 25;break;case TextStyle.SmallTipTitle:color_ = Color.yellow;txt_Target.font = Resources.Load<Font>("Font/MSYHTTF");txt_Target.fontSize = 25;break;}txt_Target.color = color_;}

六、将上述功能添加到text组件中:

这里会定义上述的五个处理器,然后继承OnPopulateMesh,实现上面的功能:

   protected override void OnPopulateMesh(VertexHelper toFill){base.OnPopulateMesh(toFill);m_FontSpacingHandler.PopulateMesh(toFill);m_VertexColorHandler.PopulateMesh(toFill, rectTransform, color);m_TextShadowHandler.PopulateMesh(toFill, rectTransform, color);m_TextOutlineHandler.PopulateMesh(toFill);        }

重新绘制text组件下的信息:

 [MenuItem("GameObject/UI/UGUI Plus/Text Plus")]public static void CreateTextPlus(){GameObject root = new GameObject("Text", typeof(RectTransform), typeof(TextPlus));ResetInCanvasFor((RectTransform)root.transform);root.GetComponent<TextPlus>().text = "Text Plus";var text = root.GetComponent<TextPlus>();text.text = "Text Plus";text.color = Color.black;text.alignment = TextAnchor.MiddleCenter;root.transform.localPosition = Vector3.zero;}public static void TextSpacingGUI(SerializedProperty m_UseTextSpacing, SerializedProperty m_TextSpacing, ref bool m_TextSpacingPanelOpen){LayoutF(() =>{            EditorGUILayout.PropertyField(m_UseTextSpacing);if (m_UseTextSpacing.boolValue){Space();LayoutH(() => {EditorGUI.PropertyField(GUIRect(0, 18), m_TextSpacing, new GUIContent());});}}, "Text Spacing", ref m_TextSpacingPanelOpen, true);}public static void VertexColorGUI(SerializedProperty m_UseVertexColor, SerializedProperty m_VertexTopLeft, SerializedProperty m_VertexTopRight, SerializedProperty m_VertexBottomLeft, SerializedProperty m_VertexBottomRight, SerializedProperty m_VertexColorFilter, SerializedProperty m_VertexColorOffset, ref bool m_VertexColorPanelOpen){LayoutF(() => {EditorGUILayout.PropertyField(m_UseVertexColor);if (m_UseVertexColor.boolValue){Space();LayoutH(() => {EditorGUI.PropertyField(GUIRect(0, 18), m_VertexTopLeft, new GUIContent());Space();EditorGUI.PropertyField(GUIRect(0, 18), m_VertexTopRight, new GUIContent());});Space();LayoutH(() => {EditorGUI.PropertyField(GUIRect(0, 18), m_VertexBottomLeft, new GUIContent());Space();EditorGUI.PropertyField(GUIRect(0, 18), m_VertexBottomRight, new GUIContent());});Space();m_VertexColorFilter.enumValueIndex = (int)(VertexColorHandler.ColorFilterType)EditorGUILayout.EnumPopup(new GUIContent("Filter"), (VertexColorHandler.ColorFilterType)m_VertexColorFilter.enumValueIndex);Vector2 newOffset = EditorGUILayout.Vector2Field("Offset", m_VertexColorOffset.vector2Value);newOffset.x = Mathf.Clamp(newOffset.x, -1f, 1f);newOffset.y = Mathf.Clamp(newOffset.y, -1f, 1f);m_VertexColorOffset.vector2Value = newOffset;Space();}}, "Vertex Color", ref m_VertexColorPanelOpen, true);}public static void TextShadowGUI(SerializedProperty m_UseShadow, SerializedProperty m_ShadowColorTopLeft, SerializedProperty m_ShadowColorTopRight,SerializedProperty m_ShadowColorBottomLeft, SerializedProperty m_ShadowColorBottomRight, SerializedProperty m_ShadowEffectDistance, ref bool m_TextShadowPanelOpen){LayoutF(() =>{EditorGUILayout.PropertyField(m_UseShadow);if (m_UseShadow.boolValue){Space();LayoutH(() => {EditorGUI.PropertyField(GUIRect(0, 18), m_ShadowColorTopLeft, new GUIContent());Space();EditorGUI.PropertyField(GUIRect(0, 18), m_ShadowColorTopRight, new GUIContent());});Space();LayoutH(() => {EditorGUI.PropertyField(GUIRect(0, 18), m_ShadowColorBottomLeft, new GUIContent());Space();EditorGUI.PropertyField(GUIRect(0, 18), m_ShadowColorBottomRight, new GUIContent());});Space();EditorGUILayout.PropertyField(m_ShadowEffectDistance);}}, "Shadow", ref m_TextShadowPanelOpen, true);}public static void SimpleUseGUI(string title, ref bool m_PanelOpen, float space, SerializedProperty useThis, params SerializedProperty[] sps){LayoutF(() => {EditorGUILayout.PropertyField(useThis);if (useThis.boolValue){foreach (var s in sps){if (s != null){EditorGUILayout.PropertyField(s);}}}}, title, ref m_PanelOpen, true);}private static void ResetInCanvasFor(RectTransform root){root.SetParent(Selection.activeTransform);if (!InCanvas(root)){Transform canvasTF = GetCreateCanvas();root.SetParent(canvasTF);}if (!Transform.FindObjectOfType<UnityEngine.EventSystems.EventSystem>()){GameObject eg = new GameObject("EventSystem");eg.AddComponent<UnityEngine.EventSystems.EventSystem>();eg.AddComponent<UnityEngine.EventSystems.StandaloneInputModule>();}root.localScale = Vector3.one;root.localPosition = new Vector3(root.localPosition.x, root.localPosition.y, 0f);Selection.activeGameObject = root.gameObject;}private static bool InCanvas(Transform tf){while (tf.parent){tf = tf.parent;if (tf.GetComponent<Canvas>()){return true;}}return false;}private static Transform GetCreateCanvas(){Canvas c = Object.FindObjectOfType<Canvas>();if (c){return c.transform;}else{GameObject g = new GameObject("Canvas");c = g.AddComponent<Canvas>();c.renderMode = RenderMode.ScreenSpaceOverlay;g.AddComponent<CanvasScaler>();g.AddComponent<GraphicRaycaster>();return g.transform;}}private static void LayoutF(System.Action action, string label, ref bool open, bool box = false){bool _open = open;LayoutV(() => {_open = GUILayout.Toggle(_open,label,GUI.skin.GetStyle("foldout"),GUILayout.ExpandWidth(true),GUILayout.Height(18));if (_open){action();}}, box);open = _open;}private static Rect GUIRect(float width, float height){return GUILayoutUtility.GetRect(width, height, GUILayout.ExpandWidth(width <= 0), GUILayout.ExpandHeight(height <= 0));}private static void Space(float space = 4f){GUILayout.Space(space);}private static void LayoutH(System.Action action, bool box = false){if (box){GUIStyle style = new GUIStyle(GUI.skin.box);GUILayout.BeginHorizontal(style);}else{GUILayout.BeginHorizontal();}action();GUILayout.EndHorizontal();}private static void LayoutV(System.Action action, bool box = false){if (box){GUIStyle style = new GUIStyle(GUI.skin.box){padding = new RectOffset(6, 6, 2, 2)};GUILayout.BeginVertical(style);}else{GUILayout.BeginVertical();}action();GUILayout.EndVertical();}

工程链接: 链接:https://pan.baidu.com/s/1xsA4-DlYh0jFCgrdj3UqKw  提取码:xj3y

想了解和学习更多unity相关知识可以关注下方公众号:

Unity 关于Ugui之text组件的扩展相关推荐

  1. Unity的UGUI使用Text和Image实现文字下划线

    Unity的UGUI使用Text和Image实现文字下划线 引子效果 设置 原文链接 引子效果 写需求的时候搜了一些文字加下划线的方法,UGUI的Text,大都需要写一堆代码来封装Text,比较麻烦. ...

  2. Unity 之 UGUI Layout自动布局组件详解

    Unity 之 UGUI Layout自动布局组件详解 1,布局元素 (Layout Element) 2,水平布局组 (Horizontal Layout Group) 3,垂直布局组 (Verti ...

  3. 「Unity」UGUI的Text实现首行缩进的办法

    我的Unity版本:5.3.5f1 直接说正事 Unity的Text组件,想实现代码拿到一段话,在前面加个缩进,让之后的字符依次后移. 有人觉得很简单,然后就这样写了: 但是尝试过的人就会发现,如果用 ...

  4. 零基础入门 Unity 之 UGUI 详解专栏 | 寻找C站宝藏

    零基础入门 Unity 之 UGUI 详解专栏 | 寻找C站宝藏 六大推荐理由 理由一:系统 理由二:详细 理由三:专业 理由四:图解 理由五:深度 理由六:实例 一键直达:<UGUI 控件详解 ...

  5. Unity 之 UGUI Dropdown下拉选单组件详解

    Unity 之 UGUI Dropdown下拉选单组件详解 1,属性面板 1), Dropdown的组成 2,代码操作 3,使用实例 1), 控制菜单展开方向 4,相关扩展 1), Lua中动态添加O ...

  6. Unity 之 UGUI Toggle组件介绍和简例

    Unity 之 UGUI Toggle组件介绍和简例 复合组件Toggle的组成: Toggle:自身挂载Toggle组件,并且对有对子物体的引用. Background:就是个Image组件,用来当 ...

  7. Unity 之 UGUI Dropdown组件使用简析

    Unity 之 UGUI Dropdown组件使用简析 官方释义 示例展示 代码操作 官方源码 官方释义 官方文档:https://docs.unity3d.com/Manual/script-Dro ...

  8. Unity中Text组件段首如何缩进两个字符

    Unity中Text组件段首如何缩进两个字符 我们在使用Unity的Text组件时,如果想实现段首缩进两个字符的功能,一般情况下会想到添加空格的字符如"\0\0",来实现,但是应该 ...

  9. Unity 之 UGUI RectTransform矩形变换组件详解

    Unity 之 UGUI RectTransform矩形变换组件详解 1,属性面板 2,详细信息 3,代码操作 4,使用实例 4.1 传说中的自适应 4.2 锚点的另一种使用方式: 4.3 蓝图和原始 ...

最新文章

  1. 两种方式(goto语句以及while循环)实现C语言关机小程序
  2. ipython安装教程-CentOS 5安装IPython
  3. Instagram为何如此受欢迎?
  4. SilverLight学习笔记--如何解决Button不响应MouseLeftButtonDown与MouseLeftButtonUp事件的问题...
  5. [摘]一张图 , oracle merge用法:
  6. 中两个数做减法_四年级数学下册 | 第1单元加、减法的意义和各部 分之间的关系(P13)...
  7. leetcode1103. 分糖果 II 该模拟就模拟,别老想着优化
  8. win7安装TensorFlow-gpu 2.3详细教程(CUDA10.1,cuDNN7)
  9. twitter finagle java_java搭建finagle(2)
  10. linux运行win7,Windows7 上运行docker实战
  11. js工作笔记003---js编写习惯_提高网页显示速度
  12. Kali Linux渗透测试实战 1.3 渗透测试的一般化流程
  13. 【xcode 插件】快速插件安装
  14. Lightroom Classic教程:如何显示堆叠?
  15. IHttpHandler给图片加水印
  16. 如何在ImageRanger中设置人脸识别来整理照片分类
  17. 雨棚板弹性法计算简图_钢结构雨篷图纸计算书
  18. Python IDE(集成开发工具)的下载安装教程
  19. 断网怎么装网卡驱动?
  20. VS2017编译SQLite3生成.lib

热门文章

  1. 考研英语词汇文章3-Salt
  2. 【重识云原生】第六章容器基础6.4.5.3节——Deployment实现原理解析
  3. PTGui Pro12垂直线纠正
  4. JAVA将证件号打星号
  5. 第十五期“AI未来说·青年学术论坛”带你了解大数据运用
  6. 基于Java(SSM框架)实现的购物网站系统【100010082】
  7. vue实现聊天框,模拟对话附上html
  8. 正版示波器软件安装教程NS-Scope
  9. 山东移动咪咕MG2000_KJ_S905L2B_RTL8822BS_线刷固件包
  10. 【PCB干货】是开窗还是盖油?想搞懂过孔工艺,看这篇就够了!