【Unity实战篇 】 | Unity实现UGUI颜色渐变,支持透明渐变

请添加图片描述

      • 前言
  • 【Unity实战篇 】 | Unity实现UGUI颜色渐变,支持透明渐变
    • 一、双层颜色渐变
      • 1.1 组件属性面板
      • 1.2 效果及代码
    • 二、多层颜色渐变
      • 2.1 组件属性面板
      • 2.2 效果及代码
  • 总结

请添加图片描述


前言

  • 在Unity中UGUI的实现图片和文字颜色渐变效果是一个很常见的需求。
  • 下面就来看一下颜色渐变效果是怎样实现的吧。

【Unity实战篇 】 | Unity实现UGUI颜色渐变,支持透明渐变

效果展示
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述

一、双层颜色渐变

双层颜色渐变 是游戏中用到的比较多的效果,实现方式也比较简单,下面看下效果和实现方式。

1.1 组件属性面板

在这里插入图片描述

属性说明
Direction方向
Color1颜色1
Color2颜色2
range偏移量
isFlip是否翻转

通过配置参数可以调节渐变的颜色、偏移量和翻转效果。


1.2 效果及代码

在这里插入图片描述

完整代码如下:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Gradient : BaseMeshEffect
{public enum DirectionType{Horizontal,Vertical,}[SerializeField]private DirectionType m_Direction = DirectionType.Vertical;[SerializeField]public Color32 m_Color1 = Color.white;[SerializeField]public Color32 m_Color2 = Color.white;[SerializeField]private float m_Range = 0f;[SerializeField]private bool m_Flip = false;public override void ModifyMesh(VertexHelper vh){if (!IsActive() || vh.currentVertCount <= 0){return;}int count = vh.currentVertCount;List<UIVertex> vertices = new List<UIVertex>();for (int i = 0; i < count; i++){UIVertex uIVertex = new UIVertex();vh.PopulateUIVertex(ref uIVertex, i);vertices.Add(uIVertex);}switch (m_Direction){case DirectionType.Horizontal:DrawHorizontal(vh, vertices, count);break;case DirectionType.Vertical:DrawVertical(vh, vertices, count);break;default:break;}}private void DrawVertical(VertexHelper vh, List<UIVertex> vertices, int count){float topY = vertices[0].position.y;float bottomY = vertices[0].position.y;for (int i = 0; i < count; i++){float y = vertices[i].position.y;if (y > topY){topY = y;}else if (y < bottomY){bottomY = y;}}float height = topY - bottomY;for (int i = 0; i < count; i++){UIVertex vertex = vertices[i];Color32 color = Color.white;if (m_Flip){color = Color32.Lerp(m_Color2, m_Color1, 1 - (vertex.position.y - bottomY) / height * (1f - m_Range));}else{color = Color32.Lerp(m_Color2, m_Color1, (vertex.position.y - bottomY) / height * (1f - m_Range));}vertex.color = color;vh.SetUIVertex(vertex, i);}}private void DrawHorizontal(VertexHelper vh, List<UIVertex> vertices, int count){float topX = vertices[0].position.x;float bottomX = vertices[0].position.x;for (int i = 0; i < count; i++){float y = vertices[i].position.x;if (y > topX){topX = y;}else if (y < bottomX){bottomX = y;}}float height = topX - bottomX;for (int i = 0; i < count; i++){UIVertex vertex = vertices[i];Color32 color = Color.white;if (m_Flip){color = Color32.Lerp(m_Color1, m_Color2, 1 - (vertex.position.x - bottomX) / height * (1f - m_Range));}else{color = Color32.Lerp(m_Color1, m_Color2, (vertex.position.x - bottomX) / height * (1f - m_Range));}vertex.color = color;vh.SetUIVertex(vertex, i);}}
}

使用ModifyMesh()方法(通常在实现IMeshModifier接口时被重写,这个接口允许开发者自定义UI元素在渲染时的外观)进行网格修改。

比如垂直渐变时,找到图形的顶部和底部顶点并计算出高度差,然后计算出所有顶点位置的颜色值,并根据设置好的颜色进行赋值即可完成颜色渐变效果。


二、多层颜色渐变

在有些情况下双层渐变可能满足不了需求,需要用到多层颜色渐变的效果。

2.1 组件属性面板

在这里插入图片描述

属性说明
Direction方向
ColorArray颜色数组
Flip是否翻转

2.2 效果及代码

在这里插入图片描述

完整代码如下:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Gradients : BaseMeshEffect
{/// <summary>/// 渐变方向/// </summary>public enum DirectionType{Horizontal,Vertical,}[SerializeField]private DirectionType direction = DirectionType.Horizontal;[SerializeField]private Color32[] m_ColorArray = new Color32[2] { Color.black, Color.white };[SerializeField]private bool m_Flip = false;//每一个文字的顶点数int m_VertexCountPer = 6;//顶点缓存List<UIVertex> m_VertexCache = new List<UIVertex>();//绘制使用的顶点列表List<UIVertex> m_VertexList = new List<UIVertex>();public override void ModifyMesh(VertexHelper vh){if (!IsActive() || m_ColorArray.Length < 2) { return; }vh.GetUIVertexStream(m_VertexCache);if (m_VertexCache.Count == 0) { return; }switch (direction){case DirectionType.Horizontal:ApplyGradient_Horizontal(m_VertexCache, m_ColorArray.Length);break;case DirectionType.Vertical:ApplyGradient_Vertical(m_VertexCache, m_ColorArray.Length);break;default:break;}vh.Clear();vh.AddUIVertexTriangleStream(m_VertexList);m_VertexCache.Clear();m_VertexList.Clear();}void ApplyGradient_Horizontal(List<UIVertex> vertexCache, int colorCount){for (int n = 0; n < m_VertexCache.Count / 6; n++){UIVertex lastVertexLT = new UIVertex();UIVertex lastVertexLB = new UIVertex();UIVertex lastVertexRT = new UIVertex();UIVertex lastVertexRB = new UIVertex();for (int i = 0; i < colorCount - 1; i++){UIVertex vertexRT;UIVertex vertexLT;UIVertex vertexRB;UIVertex vertexLB;//翻转if (m_Flip){//右上角和右下角if (i == 0){vertexRT = CalcVertex(vertexCache[n * m_VertexCountPer + 1], m_ColorArray[i]);vertexRB = CalcVertex(vertexCache[n * m_VertexCountPer + 2], m_ColorArray[i]);}else{vertexRT = lastVertexLT;vertexRB = lastVertexLB;}//左上角和左下角if (i == colorCount - 2){vertexLT = CalcVertex(vertexCache[n * m_VertexCountPer + 0], m_ColorArray[i + 1]);vertexLB = CalcVertex(vertexCache[n * m_VertexCountPer + 4], m_ColorArray[i + 1]);}else{vertexLT = CalcVertex(vertexCache[n * m_VertexCountPer + 0], vertexCache[n * m_VertexCountPer + 1],(colorCount - i - 2) * 1f / (colorCount - 1), m_ColorArray[i + 1]);vertexLB = CalcVertex(vertexCache[n * m_VertexCountPer + 4], vertexCache[n * m_VertexCountPer + 2],(colorCount - i - 2) * 1f / (colorCount - 1), m_ColorArray[i + 1]);}lastVertexLT = vertexLT;lastVertexLB = vertexLB;}else{//左上角和左下角if (i == 0){vertexLT = CalcVertex(vertexCache[n * m_VertexCountPer + 0], m_ColorArray[i]);vertexLB = CalcVertex(vertexCache[n * m_VertexCountPer + 4], m_ColorArray[i]);}else{vertexLT = lastVertexRT;vertexLB = lastVertexRB;}//右上角和右下角if (i == colorCount - 2){vertexRT = CalcVertex(vertexCache[n * m_VertexCountPer + 1], m_ColorArray[i + 1]);vertexRB = CalcVertex(vertexCache[n * m_VertexCountPer + 2], m_ColorArray[i + 1]);}else{vertexRT = CalcVertex(vertexCache[n * m_VertexCountPer + 1], vertexCache[n * m_VertexCountPer + 0],(colorCount - i - 2) * 1f / (colorCount - 1), m_ColorArray[i + 1]);vertexRB = CalcVertex(vertexCache[n * m_VertexCountPer + 2], vertexCache[n * m_VertexCountPer + 4],(colorCount - i - 2) * 1f / (colorCount - 1), m_ColorArray[i + 1]);}lastVertexRT = vertexRT;lastVertexRB = vertexRB;}m_VertexList.Add(vertexLT);m_VertexList.Add(vertexRT);m_VertexList.Add(vertexRB);m_VertexList.Add(vertexRB);m_VertexList.Add(vertexLB);m_VertexList.Add(vertexLT);}}}void ApplyGradient_Vertical(List<UIVertex> vertexCache, int colorCount){for (int n = 0; n < m_VertexCache.Count / 6; n++){UIVertex lastVertexLT = new UIVertex();UIVertex lastVertexRT = new UIVertex();UIVertex lastVertexLB = new UIVertex();UIVertex lastVertexRB = new UIVertex();for (int i = 0; i < colorCount - 1; i++){UIVertex vertexRT;UIVertex vertexLT;UIVertex vertexRB;UIVertex vertexLB;//翻转if (m_Flip){//左下角和右下角if (i == 0){vertexLB = CalcVertex(vertexCache[n * m_VertexCountPer + 4], m_ColorArray[i]);vertexRB = CalcVertex(vertexCache[n * m_VertexCountPer + 2], m_ColorArray[i]);}else{vertexLB = lastVertexLT;vertexRB = lastVertexRT;}//左上角和右上角if (i == colorCount - 2){vertexLT = CalcVertex(vertexCache[n * m_VertexCountPer + 0], m_ColorArray[i + 1]);vertexRT = CalcVertex(vertexCache[n * m_VertexCountPer + 1], m_ColorArray[i + 1]);}else{vertexLT = CalcVertex(vertexCache[n * m_VertexCountPer + 0], vertexCache[n * m_VertexCountPer + 4],(colorCount - i - 2) * 1f / (colorCount - 1), m_ColorArray[i + 1]);vertexRT = CalcVertex(vertexCache[n * m_VertexCountPer + 1], vertexCache[n * m_VertexCountPer + 2],(colorCount - i - 2) * 1f / (colorCount - 1), m_ColorArray[i + 1]);}lastVertexLT = vertexLT;lastVertexRT = vertexRT;}else{//左上角和右上角if (i == 0){vertexLT = CalcVertex(vertexCache[n * m_VertexCountPer + 0], m_ColorArray[i]);vertexRT = CalcVertex(vertexCache[n * m_VertexCountPer + 1], m_ColorArray[i]);}else{vertexLT = lastVertexLB;vertexRT = lastVertexRB;}//左下角和右下角if (i == colorCount - 2){vertexLB = CalcVertex(vertexCache[n * m_VertexCountPer + 4], m_ColorArray[i + 1]);vertexRB = CalcVertex(vertexCache[n * m_VertexCountPer + 2], m_ColorArray[i + 1]);}else{vertexLB = CalcVertex(vertexCache[n * m_VertexCountPer + 4], vertexCache[n * m_VertexCountPer + 0],(colorCount - i - 2) * 1f / (colorCount - 1), m_ColorArray[i + 1]);vertexRB = CalcVertex(vertexCache[n * m_VertexCountPer + 2], vertexCache[n * m_VertexCountPer + 1],(colorCount - i - 2) * 1f / (colorCount - 1), m_ColorArray[i + 1]);}lastVertexLB = vertexLB;lastVertexRB = vertexRB;}m_VertexList.Add(vertexLT);m_VertexList.Add(vertexRT);m_VertexList.Add(vertexRB);m_VertexList.Add(vertexRB);m_VertexList.Add(vertexLB);m_VertexList.Add(vertexLT);}}}/// <summary>/// 计算顶点数据(只计算颜色)/// </summary>UIVertex CalcVertex(UIVertex vertex, Color32 color){vertex.color = color;return vertex;}/// <summary>/// 计算顶点数据/// </summary>UIVertex CalcVertex(UIVertex vertexA, UIVertex vertexB, float ratio, Color32 color){UIVertex vertexTemp = new UIVertex();vertexTemp.position = (vertexB.position - vertexA.position) * ratio + vertexA.position;vertexTemp.color = color;vertexTemp.normal = (vertexB.normal - vertexA.normal) * ratio + vertexA.normal;vertexTemp.tangent = (vertexB.tangent - vertexA.tangent) * ratio + vertexA.tangent;vertexTemp.uv0 = (vertexB.uv0 - vertexA.uv0) * ratio + vertexA.uv0;vertexTemp.uv1 = (vertexB.uv1 - vertexA.uv1) * ratio + vertexA.uv1;return vertexTemp;}
}

使用时将该渐变脚本挂载到Image或者Text组件上,然后配置自己所需的参数即可。


总结

  • 本文提供了两种UGUI颜色渐变的方法,可以满足多数使用情景。
  • 如果有更好的解决方案,也可以在评论区指出一起分享学习!

  • 🎬 博客主页:https://xiaoy.blog.csdn.net

  • 🎥 本文由 呆呆敲代码的小Y 原创 🙉

  • 🎄 学习专栏推荐:Unity系统学习专栏

  • 🌲 游戏制作专栏推荐:游戏制作

  • 🌲Unity实战100例专栏推荐:Unity 实战100例 教程

  • 🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

  • 📆 未来很长,值得我们全力奔赴更美好的生活✨

  • ------------------❤️分割线❤️-------------------------

请添加图片描述请添加图片描述请添加图片描述

请添加图片描述

资料白嫖,技术互助

学习路线指引(点击解锁)知识定位人群定位
🧡 Unity系统学习专栏 🧡入门级本专栏从Unity入门开始学习,快速达到Unity的入门水平
💛 Unity实战类项目 💛进阶级计划制作Unity的 100个实战案例!助你进入Unity世界,争取做最全的Unity原创博客大全。
❤️ 游戏制作专栏 ❤️ 难度偏高分享学习一些Unity成品的游戏Demo和其他语言的小游戏!
💚 游戏爱好者万人社区💚 互助/吹水数万人游戏爱好者社区,聊天互助,白嫖奖品
💙 Unity100个实用技能💙 Unity查漏补缺针对一些Unity中经常用到的一些小知识和技能进行学习介绍,核心目的就是让我们能够快速学习Unity的知识以达到查漏补缺

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/22023.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习中的集成学习

&#x1f4ac;内容概要 1 集成学习概述及主要研究领域 2 简单集成技术  2.1 投票法  2.2 平均法  2.3 加权平均 3 高级集成技术  3.1 Bagging  3.2 Boosting  3.3 Bagging vs Boosting 4 基于Bagging和Boosting的机器学习算法  4.1 sklearn中的Bagging算法  4.2 sklea…

1961. 检查字符串是否为数组前缀 - 力扣

1. 题目 给你一个字符串 s 和一个字符串数组 words &#xff0c;请你判断 s 是否为 words 的 前缀字符串 。 字符串 s 要成为 words 的 前缀字符串 &#xff0c;需要满足&#xff1a;s 可以由 words 中的前 k&#xff08;k 为 正数 &#xff09;个字符串按顺序相连得到&#xf…

大型语言模型的工作原理(LLM:从零学起)

目录 一、说明 二、LLM如何运作 三、预训练&#xff1a;基本模型 四、微调&#xff1a;培训助手 五、RLHF&#xff1a;从人类反馈中强化学习 六、提示工程 七、总结 一、说明 这是我们谈论LLM系列的第二篇文章。在本文中&#xff0c;我们旨在为大型语言模型 &#xff08;LLM&am…

企业微信hook接口协议,ipad协议http,chatid转群id

chatid转群id 参数名必选类型说明uuid是String每个实例的唯一标识&#xff0c;根据uuid操作具体企业微信 请求示例 {"uuid":"3240fde0-45e2-48c0-90e8-cb098d0ebe43","chatid":"wrO9o4EAAAeR_nSlmjeX1RWrKAKxN8jQ" } 返回示例 {&…

【银河麒麟V10服务器OS-系统根分区扩容】指导教程手册

【银河麒麟V10服务器OS-系统根分区扩容】指导教程手册 环境信息&#xff1a;VMware虚拟软件16.0 首先查看KylinOS服务器版本&#xff1a;nkvers 备注&#xff1a; (Tercel) 版本是 V10 SP1 版本&#xff0c; (Sword) 版本是 V10 SP2 版本&#xff0c; (Lance) 版本是 V10 …

UE4 使用样条线做鱼儿封闭路径动画

描述&#xff1a;鱼儿的游动动画的特点 1.通常是始终保持Y (Pitch)轴角度不变 2.调头的时候改变的是Z轴角度 效果&#xff1a;调头的时候比较自然 蓝图&#xff1a; 最后为了让鱼儿有恒定的游动速度&#xff0c;增加以下蓝图节点&#xff0c;游动速度为50

CTFHUB-技能树-web-web前置技能-HTTP协议全

目录 1.请求方式 2.302跳转 3.Cookie 4.基础认证 5.响应包源码 1.请求方式 curl -v -X http://challenge-3022c877a8dcedeb.sandbox.ctfhub.com:10800/index.php 2.302跳转 参考链接&#xff1a;http://t.csdnimg.cn/aqdNG 301——永久性重定向。该状态码表示请求的资源已…

Avue-data数据大屏显示柱状图(附Demo讲解)

目录 前言1. 接口方式2. SQL查询 前言 由于网上对这部分的知识点相对较少&#xff0c;研究半天的框架最终输出结果 此文主要以记录总结的方式展示如何使用数据库以及接口方式 需要明白柱状图的返回数据格式&#xff1a; #柱状图数据格式 {"categories": ["苹…

组织是什么,为什么需要组织,为什么需要公司

垂直组织 组织架构设计&#xff0c;曾经咱们多个章节进行沟通&#xff0c;今天再回到组织本身。不妨可以思考一个这样的问题&#xff0c;或者随访身边的老板或者朋友&#xff0c;让他们绘制一个组织架构图&#xff0c;或者绘制一个本组织一个视图&#xff0c;得到以下图的示意…

[Redis]Set类型

集合类型也是保存多个字符串类型的元素的&#xff0c;但和列表类型不同的是&#xff0c;集合中 1&#xff09;元素之间是无序的 2&#xff09;元素不允许重复 一个集合中最多可以存储2^32-1个元素。 Redis 除了支持集合内的增删查改操作&#xff0c;同时还支持多个集合取交…

盲盒小程序库存管理的关键策略

随着盲盒经济的兴起&#xff0c;越来越多的商家开始投入盲盒小程序的开发与运营。然而&#xff0c;在享受市场红利的同时&#xff0c;库存管理的问题也随之而来。合理的库存管理不仅能够满足用户需求&#xff0c;还能有效优化库存周转率&#xff0c;提升商家的盈利能力。本文将…

有光摄影分享网站系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;基础数据管理&#xff0c;论坛管理&#xff0c;足球资讯管理&#xff0c;球队管理 前台账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;活动&#xff0c;论坛…

HCIA--OSPF实验(复习)

实验拓扑&#xff1a; 实验思路&#xff1a; 1.规划IP&#xff0c;配置环回&#xff0c;接口IP 2.把R1&#xff0c;R2优先级改为0&#xff0c;让R1、R2放弃选举&#xff0c; [r1]interface g0/0/0 [r1-GigabitEthernet0/0/0]ospf dr-priority 0 <r1>reset ospf…

数据结构——哈希表、哈希桶

哈希概念 顺序结构以及平衡树中&#xff0c;元素关键码与其存储位置之间没有对应的关系&#xff0c;因此在查找一个元素时&#xff0c;必须要经过关键码的多次比较&#xff0c;顺序查找时间复杂度为O(N),平衡树中为树的高度,即O(logN),搜索的效率取决于搜索过程种元素的比较次…

ElasticSearch学习笔记之一:介绍及EFK部署

1. 系统概述 The Elastic Stack&#xff0c;包括Elasticsearch、Kibana、Beats和Logstash&#xff08;也成为ELK Stack&#xff09; Elasticsearch&#xff1a;简称ES&#xff0c;是一个开源的高扩展的分布式全文搜索引擎&#xff0c;是整个Elastic Stack技术栈的核心。它可以…

docker安装redis以及持久化

为了避免当虚拟机关机后redis数据丢失的情况&#xff0c;redis需要持久化。所以要挂载数据卷 创建数据和配置存放的目录 [root192 data]# pwd /root/data [root192 data]# mkdir -p /root/data/redis/conf && chmod 777 /root/data/redis/conf [root192 data]# mkdir …

怎么找抖音视频素材?下载抖音的素材视频网站分享给你

在这个视觉印象至关重要的时代&#xff0c;选用高质量的视频素材对于制作抖音视频来说是关键。如果你正在寻找适合的视频素材来丰富你的抖音创作&#xff0c;以下这份详细的视频素材网站指南将帮助你迈出第一步。 蛙学府网 蛙学府网提供了丰富多样的视频素材&#xff0c;包括动…

香橙派Orange AI Pro / 华为昇腾310芯片 部署自己训练的yolov8模型进行中国象棋识别

香橙派Orange AI Pro / 华为昇腾310芯片 部署自己训练的yolov8模型进行中国象棋识别 一、香橙派简介1.1、香橙派 AI Pro 硬件资源介绍1.2、华为昇腾310&#xff08;Ascend310&#xff09; 简介1.3、 昇腾310AI能力和CANN 简介昇腾310 NPU简介 二、远程环境配置2.1、ssh2.2、vnc…

沈阳 2024年 融资融券怎么开通,利率多少?

融资融券是什么&#xff0c;为什么能赚钱&#xff0c;怎么赚更多&#xff0c;怎么少付利息 100个4.2% 如果你发现了好股票、好机会&#xff0c;但目前券商的融资利率较高&#xff0c;可以考虑转户并选择低利率的券商&#xff0c; 同时需要注意开通条件和转户产生的成本费用。…

新书推荐:1.3 内存管理模式

本节必须掌握的知识点&#xff1a; 4GB虚拟空间 虚拟内存 多任务切换 1.3.1 4GB虚拟空间 ■Win16操作系统 Windows1.0版本为16位操作系统&#xff0c;支持16位处理器实模式&#xff0c;最大寻址空间为1MB。Win16操作系统的内存管理非常简单&#xff0c;采用分段内存管理模式…