当前位置: 首页 > news >正文

Unity扩展 Text 彩虹文本

本文章用于原生组件 Text 的扩展 TextRainbow,对于新版TextMeshPro不适用。

一、效果预览图:

默认:

随机:

循环:

二、原理

通过强制刷新顶点数据,来修改颜色。

通过Unity中自带的 BaseMeshEffect 抽象类,可以直接修改UI元素的网格,从而达到比如阴影,描边,UV顶点颜色等视觉效果。

新建一个脚本继承 BaseMeshEffect 抽象类,通过 ModifyMesh 方法来自定义想要的效果。 ModifyMesh 方法中自带参数类型 VertexHelper,通过参数类型中提供的 GetUIVertexStream、PopulateUIVertex 和 SetUIVertex 方法来获取当前网格的顶点数据并重新设置回去。

彩虹颜色的方式有很多种,这里推荐使用渐变 Gradient 去做比较方便。Gradient 的颜色设置和获取在代码中已有展示,没啥好说的。

对于颜色的显示三种方式,循环模式是通过Update方法驱动渐变颜色索引实现的,并且添加是否忽略引擎的TimeScale影响。

三、代码

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Random = UnityEngine.Random;
[RequireComponent(typeof(Text))]
public class TextRainbow : BaseMeshEffect
{public enum VerticesColorType{None,Random,Loop}[SerializeField] protected Text target;/// <summary>/// 彩虹条/// </summary>public Gradient gradient = new();/// <summary>/// 彩虹条颜色数量/// </summary>private int ColorCount => gradient.colorKeys.Length;/// <summary>/// 当前索引下标 0 ~ gradientColors/// </summary>private int _index = 0;/// <summary>/// 进度,0 ~ 1/// </summary>private float _timeProcess = 0;private bool _openRainbow = false;/// <summary>/// 存在彩虹文本/// </summary>private bool _haveRainbow = false;private readonly List<UIVertex> _vertices = new();/// <summary>/// 滚动速度/// </summary>public float ScrollSpeed = 3f;/// <summary>/// 打开彩虹/// </summary>public bool OpenRainbow{get => _openRainbow;set{if (_openRainbow == value){return;}_openRainbow = value;UpdateIndex();HaveRainbowCondition();target.SetVerticesDirty();}}/// <summary>/// 彩虹颜色类型/// </summary>private VerticesColorType _colorType = VerticesColorType.None;public VerticesColorType ColorType{get => _colorType;set{if (_colorType == value){return;}_colorType = value;UpdateIndex();if (_openRainbow){target.SetVerticesDirty();}}}/// <summary>/// 忽略时间缩放/// </summary>public bool unScaledTime = false;public string Text{get => target.text;set => SetText(value);}protected override void Awake(){_index = 0;if (!target){target = GetComponent<Text>();}}private void Update(){if (!OpenRainbow){return;}if (!_haveRainbow){return;}if (_colorType != VerticesColorType.Loop) return;_timeProcess += (unScaledTime ? Time.unscaledDeltaTime : Time.deltaTime) * ScrollSpeed;if (!(_timeProcess >= 1)) return;_timeProcess -= 1;_index++;target.SetVerticesDirty();if (_index >= ColorCount){_index = 0;}}
#if UNITY_EDITORprotected override void Reset(){base.Reset();target = GetComponent<Text>();}
#endifpublic override void ModifyMesh(VertexHelper vh){if (!_haveRainbow){return;}if (!IsActive() || vh.currentIndexCount == 0){return;}_vertices.Clear();vh.GetUIVertexStream(_vertices);UIVertex uiVertex = new();for (var i = 0; i < vh.currentVertCount; ++i){vh.PopulateUIVertex(ref uiVertex, i);uiVertex.color = CalcColor(i);vh.SetUIVertex(uiVertex, i);}}private Color CalcColor(int index){if (!OpenRainbow){return target.color;}index /= 4;index += _index;if (index >= ColorCount){index %= ColorCount;}return gradient.Evaluate(gradient.colorKeys[index].time);}private void SetText(string text){if (string.IsNullOrEmpty(text)){_haveRainbow = false;target.text = string.Empty;return;}_haveRainbow = OpenRainbow;target.text = text;}private void HaveRainbowCondition(){if (string.IsNullOrEmpty(Text)){_haveRainbow = false;return;}_haveRainbow = OpenRainbow;}private void UpdateIndex(){switch (_colorType){case VerticesColorType.Random:_index = Random.Range(0, ColorCount);break;case VerticesColorType.None:case VerticesColorType.Loop:default:_index = 0;break;}}
}

 面板扩展:

using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(TextRainbow), true)]
[CanEditMultipleObjects]
public class TextRainbowEditor : Editor
{private const int NumberOfColors = 7;private TextRainbow Target => (TextRainbow)target;private SerializedProperty _component;private SerializedProperty _unScaledTime;protected void OnEnable(){_component = serializedObject.FindProperty("target");_unScaledTime = serializedObject.FindProperty("unScaledTime");}public override void OnInspectorGUI(){serializedObject.Update();GUI.enabled = false;EditorGUILayout.PropertyField(_component);GUI.enabled = true;EditorGUI.BeginChangeCheck();#region GradientEditorGUILayout.BeginHorizontal();Target.gradient = EditorGUILayout.GradientField("Gradient", Target.gradient);// 预设彩虹渐变if (GUILayout.Button("Rainbow", GUILayout.Width(80))){DrawRainbowGradient();}EditorGUILayout.EndHorizontal();#endregionTarget.ColorType = (TextRainbow.VerticesColorType)EditorGUILayout.EnumPopup("Color Type", Target.ColorType);Target.ScrollSpeed = EditorGUILayout.Slider("Scroll Speed", Target.ScrollSpeed, 0, 10);Target.OpenRainbow = EditorGUILayout.Toggle("Open Rainbow", Target.OpenRainbow);EditorGUILayout.PropertyField(_unScaledTime);EditorGUILayout.LabelField("Text");Target.Text = EditorGUILayout.TextArea(Target.Text, GUILayout.MinHeight(EditorGUIUtility.singleLineHeight * 3));if (EditorGUI.EndChangeCheck()){EditorUtility.SetDirty(Target);}serializedObject.ApplyModifiedProperties();}// 预设彩虹渐变private void DrawRainbowGradient(){var colorKeys = new GradientColorKey[NumberOfColors];for (var i = 0; i < NumberOfColors; i++){float dividend = NumberOfColors - 1;var index = i;if (i == 1){dividend = 12f;}else if (i > 1){index = i - 1;}colorKeys[i].color = Color.HSVToRGB(index / dividend, 1f, 1f);colorKeys[i].time = (float)i / (NumberOfColors - 1);}Target.gradient.colorKeys = colorKeys;Target.gradient.alphaKeys = new[]{new GradientAlphaKey(1, 0),new GradientAlphaKey(1, 1)};}
}

写出来后稍加整理就发出来了,如果有更优解(原生组件扩展)欢迎指教。


http://www.mrgr.cn/news/3156.html

相关文章:

  • SpringBoot+OSS文件上传
  • 处理 NPU 张量构造的警告与错误的指南
  • Linux 多线程
  • 基于树莓派的智能AI网关接入豆包流程:HTTP/HTTPS、MQTT、Flask、Web可视化(代码示例)
  • 【2024国赛速成系列】建模手三天必成计划
  • 交流220V转5V100MA非隔离降压芯片应用在烧水壶上的设计与实现
  • [Linux网络】基本网络命令socket编写TCP应用层实现简易计算器
  • [Meachines] [Medium] Popcorn SQLI+Upload File+PAM权限提升
  • 测试用例、测试流程模型、测试方法详解 超详细分解
  • 一款搭载远翔FP5207芯片的大功率音箱,蓝牙音箱的组成和拆解展示
  • 零基础5分钟上手亚马逊云科技核心云架构知识 - 权限管理最佳实践
  • 使用 Python 读取 Excel 和 CSV 数据并保存到数据库
  • TensorFlow库详解:Python中的深度学习框架
  • WPF Mvvm
  • springboot启动报错
  • 【ubuntu24.04】curl 配置代理
  • 自动化运维之ansible的重要模块
  • iOS 18 Beta 5:苹果的细腻之笔,绘制用户体验新画卷
  • 鸿蒙UDP封装及使用
  • 网优学习干货:2.6G仿真操作(1)