Unity中Text渐变色,和Text间距
文字渐变色代码
using UnityEngine; using System.Collections; using UnityEngine.UI; using System.Collections.Generic; [RequireComponent(typeof(Text))] public class TextVerticalGradientTwoColor : BaseMeshEffect { public Color colorTop = Color.red; public Color colorBottom = Color.green; protected TextVerticalGradientTwoColor() { } private static void setColor(List<UIVertex> verts, int index, Color32 c) { UIVertex vertex = verts[index]; vertex.color = c; verts[index] = vertex; } private void ModifyVertices(List<UIVertex> verts) { for (int i = 0; i < verts.Count; i += 6) { setColor(verts, i + 0, colorTop); setColor(verts, i + 1, colorTop); setColor(verts, i + 2, colorBottom); setColor(verts, i + 3, colorBottom); setColor(verts, i + 4, colorBottom); setColor(verts, i + 5, colorTop); } } #region implemented abstract members of BaseMeshEffect public override void ModifyMesh(VertexHelper vh) { if (!this.IsActive()) { return; } List<UIVertex> verts = new List<UIVertex>(vh.currentVertCount); vh.GetUIVertexStream(verts); ModifyVertices(verts); vh.Clear(); vh.AddUIVertexTriangleStream(verts); } #endregion }
字体渐变升级版:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; [AddComponentMenu ("UI/Effects/TextGradient")] [RequireComponent (typeof(Text))] public class UICustomTextGradient : BaseMeshEffect { public Color32 topColor = Color.white; public Color32 bottomColor = Color.black; //后面自己添加的控制中心移动属性,有时候看着渐变不顺眼,中心偏离高或者低了,就可以通过这个去调整 [RangeAttribute (0, 1)] public float center = 0.5f; public override void ModifyMesh (VertexHelper vh) { if (!IsActive ()) { return; } var count = vh.currentVertCount; if (count == 0) return; var vertexs = new List<UIVertex> (); for (var i = 0; i < count; i++) { var vertex = new UIVertex (); vh.PopulateUIVertex (ref vertex, i); vertexs.Add (vertex); } var topY = vertexs [0].position.y; var bottomY = vertexs [0].position.y; for (var i = 1; i < count; i++) { var y = vertexs [i].position.y; if (y > topY) { topY = y; } else if (y < bottomY) { bottomY = y; } } var height = topY - bottomY; for (var i = 0; i < count; i++) { var vertex = vertexs [i]; //使用处理过后的颜色 // var color = Color32.Lerp(bottomColor, topColor, (vertex.position.y - bottomY) / height); var color = CenterColor (bottomColor, topColor, (vertex.position.y - bottomY) / height); vertex.color = color; vh.SetUIVertex (vertex, i); } } //加了一个对颜色处理的函数,主要调整中心的位置 private Color32 CenterColor (Color32 bc, Color32 tc, float time) { if (center == 0) { return bc; } else if (center == 1) { return tc; } else { var centerColor = Color32.Lerp (bottomColor, topColor, 0.5f); var resultColor = tc; if (time < center) { resultColor = Color32.Lerp (bottomColor, centerColor, time / center); } else { resultColor = Color32.Lerp (centerColor, topColor, (time - center) / (1 - center)); } return resultColor; } } }
字体渐变再次升级:
using System.Collections.Generic; public enum Type { Horizontal, Vertical } public enum Blend { Override, Add, Multiply } namespace UnityEngine.UI { [AddComponentMenu("UI/Effects/UGUI_Gradient")] public class Gradient : BaseMeshEffect { [SerializeField] Type _gradientType; [SerializeField] Blend _blendMode = Blend.Multiply; [SerializeField] [Range(-1, 1)] float _offset = 0f; [SerializeField] UnityEngine.Gradient _effectGradient = new UnityEngine.Gradient() { colorKeys = new GradientColorKey[] { new GradientColorKey(Color.black, 0), new GradientColorKey(Color.white, 1) } }; #region Properties public Blend BlendMode { get { return _blendMode; } set { _blendMode = value; } } public UnityEngine.Gradient EffectGradient { get { return _effectGradient; } set { _effectGradient = value; } } public Type GradientType { get { return _gradientType; } set { _gradientType = value; } } public float Offset { get { return _offset; } set { _offset = value; } } #endregion public override void ModifyMesh(VertexHelper helper) { if (!IsActive() || helper.currentVertCount == 0) return; List<UIVertex> _vertexList = new List<UIVertex>(); helper.GetUIVertexStream(_vertexList); int nCount = _vertexList.Count; switch (GradientType) { case Type.Horizontal: { float left = _vertexList[0].position.x; float right = _vertexList[0].position.x; float x = 0f; for (int i = nCount - 1; i >= 1; --i) { x = _vertexList[i].position.x; if (x > right) right = x; else if (x < left) left = x; } float width = 1f / (right - left); UIVertex vertex = new UIVertex(); for (int i = 0; i < helper.currentVertCount; i++) { helper.PopulateUIVertex(ref vertex, i); vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate((vertex.position.x - left) * width - Offset)); helper.SetUIVertex(vertex, i); } } break; case Type.Vertical: { float bottom = _vertexList[0].position.y; float top = _vertexList[0].position.y; float y = 0f; for (int i = nCount - 1; i >= 1; --i) { y = _vertexList[i].position.y; if (y > top) top = y; else if (y < bottom) bottom = y; } float height = 1f / (top - bottom); UIVertex vertex = new UIVertex(); for (int i = 0; i < helper.currentVertCount; i++) { helper.PopulateUIVertex(ref vertex, i); vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate((vertex.position.y - bottom) * height - Offset)); helper.SetUIVertex(vertex, i); } } break; } } Color BlendColor(Color colorA, Color colorB) { switch (BlendMode) { default: return colorB; case Blend.Add: return colorA + colorB; case Blend.Multiply: return colorA * colorB; } } } }
文字间距代码:
using UnityEngine; using System.Collections; using UnityEngine.UI; using System; using System.Collections.Generic; public class Line { private int _startVertexIndex = 0; /// <summary> /// 起点索引 /// </summary> public int StartVertexIndex { get { return _startVertexIndex; } } private int _endVertexIndex = 0; /// <summary> /// 终点索引 /// </summary> public int EndVertexIndex { get { return _endVertexIndex; } } private int _vertexCount = 0; /// <summary> /// 该行占的点数目 /// </summary> public int VertexCount { get { return _vertexCount; } } public Line(int startVertexIndex,int length) { _startVertexIndex = startVertexIndex; _endVertexIndex = length * 6 - 1 + startVertexIndex; _vertexCount = length * 6; } } [AddComponentMenu("UI/Effects/TextSpacing")] public class TextSpacing : BaseMeshEffect { public float _textSpacing = 1f; public override void ModifyMesh(VertexHelper vh) { if (!IsActive() || vh.currentVertCount == 0) { return; } Text text = GetComponent<Text>(); if (text == null) { Debug.LogError("Missing Text component"); return; } List<UIVertex> vertexs = new List<UIVertex>(); vh.GetUIVertexStream(vertexs); int indexCount = vh.currentIndexCount; string[] lineTexts = text.text.Split('\n'); Line[] lines = new Line[lineTexts.Length]; //根据lines数组中各个元素的长度计算每一行中第一个点的索引,每个字、字母、空母均占6个点 for (int i = 0; i < lines.Length; i++) { //除最后一行外,vertexs对于前面几行都有回车符占了6个点 if (i == 0) { lines[i] = new Line(0, lineTexts[i].Length + 1); } else if(i > 0 && i < lines.Length - 1) { lines[i] = new Line(lines[i - 1].EndVertexIndex + 1, lineTexts[i].Length + 1); } else { lines[i] = new Line(lines[i - 1].EndVertexIndex + 1, lineTexts[i].Length); } } UIVertex vt; for (int i = 0; i < lines.Length; i++) { for (int j = lines[i].StartVertexIndex + 6; j <= lines[i].EndVertexIndex; j++) { if (j < 0 || j >= vertexs.Count) { continue; } vt = vertexs[j]; vt.position += new Vector3(_textSpacing * ((j - lines[i].StartVertexIndex) / 6), 0, 0); vertexs[j] = vt; //以下注意点与索引的对应关系 if (j % 6 <= 2) { vh.SetUIVertex(vt, (j / 6) * 4 + j % 6); } if (j % 6 == 4) { vh.SetUIVertex(vt, (j / 6) * 4 + j % 6 - 1); } } } } }