Unity制作曲线进度条

news2024/9/27 23:29:27

unity制作曲线进度条

  大家好,我是阿赵。
  在使用Unity引擎做进度条的时候,有时会遇到一个问题,如果进度条不是简单的横向、纵向或者圆形,而是任意的不规则形状,那该怎么办呢?比如这样的:
在这里插入图片描述

一、制作方法

1、准备的素材

  这个进度条的原理很简单,我们需要一张跟随这路径变化灰度的图片。这张图片大概是这样的:
在这里插入图片描述
在这里插入图片描述

  我这里使用了RGB通道作为灰度,然后Alpha通道作为显示范围。结合在一起,在Unity里面会是这样的一张图:
在这里插入图片描述

  当然,图片也有另外的做法,比如我们想在进度条上显示一些渐变色或者纹理,可以把图片的RGB通道作为纹理图片,然后Alpha通道作为灰度变化也是可以的,毕竟灰度变化其实只用一个通道就够,没必要用RGB三个通道。

2、计算过程

目的:
1.可以使用在UI上
2.通过Image的图片作为输入
3.通过Image的颜色的RGB通道作为进度条的颜色
4.通过Image的颜色的A通道作为进度条显示的进度控制
在这里插入图片描述

  颜色的计算很简单,直接获取顶点色的RGB就可以了。如果觉得纯颜色的RGB不好看,也可以再另外做一张有颜色的图片作为显示用。
  接下来是遮罩进度条的效果。因为这里我直接用了图片的RGB色的灰度渐变,所以我先取了一个RGB的灰度。如果像上面说的,RGB颜色想自己做一个有图案的进度条图片,那么其实这个进度的也可以不用RGB色,而改用图片的Alpha通道作为灰度也是可以的。
在这里插入图片描述在这里插入图片描述

  不论怎样,获得了一个图片的灰度值,然后输入一个想控制进度的值,用这个值和灰度值做减法,再用Step函数控制显示的范围。如果想过渡的地方有一个渐变的效果,可以使用SmoothStep函数。由于灰度是沿着路径渐变的,当输入的值变化时,显示范围就会沿着灰度路径而变化了。
  最后,把Step的结果作为显示的Alpha值,结合需要显示的RGB颜色,就能得到进度条最终的显示颜色和范围了。

3、灰度渐变图的制作

  这个方法的难点不在于shader的编写,而在于素材的制作。
  我这里是用3D的方式来制作这个图片的,首先建一个面片,把它的横向段数设置到1000。
在这里插入图片描述

  然后展UV,面片的最左边的u坐标是0,最右边的u坐标是1。然后做一张从左到右的渐变图。把渐变图赋予给面片。
在这里插入图片描述

  最后通过路径变形,把面片沿着路径拉伸,得到了形状。
在这里插入图片描述

最后,把这个模型渲染出来,就得到了上面的渐变灰度图了。

  这样做,勉强能得到一个分布均匀的灰度图,但并不是100%准确。如果想得到一个完全匹配百分比的变化的灰度图,比如在进度条上画上刻度,然后想输入什么百分比,图片的灰度刚好到达那个百分比,那还要想别的办法去做这张图。

三、Shader源码

Shader "azhao/CurveProgress"
{
	Properties
	{
		[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
		_Color ("Tint", Color) = (1,1,1,1)
		
		_StencilComp ("Stencil Comparison", Float) = 8
		_Stencil ("Stencil ID", Float) = 0
		_StencilOp ("Stencil Operation", Float) = 0
		_StencilWriteMask ("Stencil Write Mask", Float) = 255
		_StencilReadMask ("Stencil Read Mask", Float) = 255

		_ColorMask ("Color Mask", Float) = 15

		[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
		_min("min", Range( -1 , 1)) = 0
		_max("max", Range( 0 , 1)) = 1
		[HideInInspector] _texcoord( "", 2D ) = "white" {}

	}

	SubShader
	{
		LOD 0

		Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" "CanUseSpriteAtlas"="True" }
		
		Stencil
		{
			Ref [_Stencil]
			ReadMask [_StencilReadMask]
			WriteMask [_StencilWriteMask]
			CompFront [_StencilComp]
			PassFront [_StencilOp]
			FailFront Keep
			ZFailFront Keep
			CompBack Always
			PassBack Keep
			FailBack Keep
			ZFailBack Keep
		}


		Cull Off
		Lighting Off
		ZWrite Off
		ZTest [unity_GUIZTestMode]
		Blend SrcAlpha OneMinusSrcAlpha
		ColorMask [_ColorMask]

		
		Pass
		{
			Name "Default"
		CGPROGRAM
			
			#pragma vertex vert
			#pragma fragment frag
			#pragma target 3.0

			#include "UnityCG.cginc"
			#include "UnityUI.cginc"

			#pragma multi_compile __ UNITY_UI_CLIP_RECT
			#pragma multi_compile __ UNITY_UI_ALPHACLIP
			
			#define ASE_NEEDS_FRAG_COLOR

			
			struct appdata_t
			{
				float4 vertex   : POSITION;
				float4 color    : COLOR;
				float2 texcoord : TEXCOORD0;
				UNITY_VERTEX_INPUT_INSTANCE_ID
				
			};

			struct v2f
			{
				float4 vertex   : SV_POSITION;
				fixed4 color    : COLOR;
				half2 texcoord  : TEXCOORD0;
				float4 worldPosition : TEXCOORD1;
				UNITY_VERTEX_INPUT_INSTANCE_ID
				UNITY_VERTEX_OUTPUT_STEREO
				
			};
			
			uniform fixed4 _Color;
			uniform fixed4 _TextureSampleAdd;
			uniform float4 _ClipRect;
			uniform sampler2D _MainTex;
			uniform float4 _MainTex_ST;
			uniform float _min;
			uniform float _max;

			
			v2f vert( appdata_t IN  )
			{
				v2f OUT;
				UNITY_SETUP_INSTANCE_ID( IN );
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
				UNITY_TRANSFER_INSTANCE_ID(IN, OUT);
				OUT.worldPosition = IN.vertex;
				
				
				OUT.worldPosition.xyz +=  float3( 0, 0, 0 ) ;
				OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);

				OUT.texcoord = IN.texcoord;
				
				OUT.color = IN.color * _Color;
				return OUT;
			}

			fixed4 frag(v2f IN  ) : SV_Target
			{
				float2 uv_MainTex = IN.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
				float4 tex2DNode1 = tex2D( _MainTex, uv_MainTex );
				float grayVal = Luminance(tex2DNode1.rgb);
				float remapVal = ( grayVal - ( 1.0 - (0.0 + (( IN.color.a + 0.01 ) - 0.0) * (( _max + 1.0 ) - 0.0) / (1.0 - 0.0)) ) );
				float smoothstepVal = smoothstep( _min , _max , remapVal);
				float4 color = (float4(IN.color.r , IN.color.g , IN.color.b , ( tex2DNode1.a * smoothstepVal )));
				
			
				#ifdef UNITY_UI_CLIP_RECT
                color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
                #endif
				
				#ifdef UNITY_UI_ALPHACLIP
				clip (color.a - 0.001);
				#endif

				return color;
			}
		ENDCG
		}
	}
	
	
	
}

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

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

相关文章

【JDK 8 -收集和统计】7.1 collector 收集器

一、collect()方法 二、两个重载方法 2.1 方法一 2.2 方法二(常用) 三、Collector 的 作用 四、Collectors 的作用 > Collectors.toList() > Collectors.toMap() > Collectors.toSet() > Collectors.toColl…

基于深度强化学习的四旋翼无人机航线跟随

源自:指挥与控制学报 作者:杨志鹏 李波 甘志刚 梁诗阳 “人工智能技术与咨询” 发布 摘 要 针对无人机在空中执行航线跟随任务时无法对未知环境作出合理应对措施等问题, 提出了一种基于深度强化学习的四 旋翼无人机航线跟随方法. 通过无人机受力…

牛客: BM17 二分查找-I

牛客: BM17 二分查找-I 文章目录 牛客: BM17 二分查找-I题目描述题解思路题解代码 题目描述 题解思路 一个左端点, 一个右端点, 循环直到左右端点交叉, 取左右端点的中点 若中点的值大于目标值, 意味着目标值只可能在中点的左边, 所以右端点变为中点的前一个位置 若中点的值…

机器学习第九课--随机森林

一.什么是集成模型 对于几乎所有的分类问题(图像识别除外,因为对于图像识别问题,目前深度学习是标配),集成模型很多时候是我们的首选。比如构建一个评分卡系统,业界的标配是GBDT或者XGBoost等集成模型,主要因为它的效…

让开源数据开发平台助力提质增效!

用低代码技术平台,可以提高办公协作效率,可以让数据资源变得更有意义和价值,也可以为企业做出更理想的发展决策。作为开源数据开发平台服务商,流辰信息谨守研发初心,一直在低代码技术平台领域努力耕耘,为行…

[Linux入门]---yum软件安装及vim编辑器配置

文章目录 1.Linux软件安装包2.如何安装软件注意事项下载rzsz查看rzsz软件包安装or卸载软件原理 3.简单配置配置文件常用配置选项(测试)使用插件使用链接配置 1.Linux软件安装包 Linux的三种软件安装方法: ①源代码安装。 在Linux系统下载程序…

【C++】动态内存管理 ③ ( C++ 对象的动态创建和释放 | new 运算符 为类对象 分配内存 | delete 运算符 释放对象内存 )

文章目录 一、C 对象的动态创建和释放1、C 语言 对象的动态创建和释放 的方式2、C 语言 对象的动态创建和释放 的方式 二、代码示例 - 对象的动态创建和释放 一、C 对象的动态创建和释放 使用 C 语言中的 malloc 函数 可以为 类对象 分配内存 ; 使用 free 函数可以释放上述分配…

Redis的介绍以及简单使用

Redis(Remote Dictionary Server)是一个开源的内存数据存储系统,它以键值对的形式将数据存在内存中,并提供灵活、高性能的数据访问方式。Redis具有高速读写能力和丰富的数据结构支持,可以广泛应用于缓存、消息队列、实…

二叉搜索树(BST,Binary Search Tree)

文章目录 1. 二叉搜索树1.1 二叉搜索树概念1.2 二叉搜索树的查找1.3 二叉搜索树的插入1.4 二叉搜索树的删除 2 二叉搜索树的实现3 二叉搜索树的应用3.1二叉搜索树的性能分析 1. 二叉搜索树 1.1 二叉搜索树概念 二叉搜索树又称二叉排序树,它或者是一棵空树&#xf…

Hive行转列[一行拆分成多行/一列拆分成多列]

场景: hive有张表armmttxn_tmp,其中有一个字段lot_number,该字段以逗号分隔开多个值,每个值又以冒号来分割料号和数量,如:A3220089:-40,A3220090:-40,A3220091:-40,A3220083:-40,A3220087:-40,A3220086:-4…

LIN - 基础

LIN - 基础 概念CAN/LIN 物理层数据链路层帧格式 概念 原理 基于UART数据格式、主从结构 串行通讯 拓扑 LIN网络中有且只有一个主节点,其他都是从节点 优缺点 功能简单 实时性低 成本低 单主多从,不存在冲突,无需仲裁 主任务/从任务 主任务&…

电脑出现找不到msvcp120.dll无法继续执行代码,不用担心多种方法帮你搞定

今天,我想和大家分享的文章是“msvcp120.dll丢失的修复方法”。我相信,对于我们很多人来说,电脑是我们学习、娱乐的重要工具,而当电脑出现问题时,我们往往束手无策。因此,我希望通过今天的文章,…

笔记-搭建和使用docker-registry私有镜像仓库

笔记-搭建和使用docker-registry私有镜像仓库 拉取/安装registry镜像 和 对应的ui镜像 如果有网络可以直接拉取镜像 docker pull registry docker pull hyper/docker-registry-web没有网络可以使用我导出好的离线镜像tar包, 下载地址https://wwzt.lanzoul.com/i3im1194z12d …

积分值和面积、对称性

积分的基本含义要从积分符号说起,积分号含有加号的意思, ∫ a b f ( x ) d x \int ^b_af(x)dx ∫ab​f(x)dx可以理解为:区间[a,b]无限细分为无穷多个dx,无穷多个f(x)乘以dx的累积和。根据上面的描述,面积可以理解为 ∫ a b ∣ f (…

信息检索与数据挖掘 | (二)布尔检索与倒排索引

文章目录 📚词项-文档关联矩阵🐇相关名词🐇词项-文档关联矩阵的布尔查询处理 📚倒排索引🐇关于索引🐇建立索引🐇基于倒排索引的布尔查询处理🐇查询优化 📚字典数据结构&a…

Cpp/Qt-day040920Qt

目录 时钟 头文件&#xff1a;Widget.h: 源文件:Widget.c: 效果图&#xff1a; 思维导图 时钟 头文件&#xff1a;Widget.h: #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPaintEvent> #include <QPainter> #include <QTime>…

[BSidesCF 2019]Kookie

1.开启环境 2.一开始没仔细看&#xff0c;就看到login as admin 所以输了admin&#xff0c;123 想去爆破密码&#xff0c;但是没啥用 3&#xff0c;又回去看&#xff0c;看到cookie&#xff0c;就抓包&#xff0c;加上cookie usernameadmin

学习笔记|模数转换器|ADC原理|STC32G单片机视频开发教程(冲哥)|第十七集:ADC采集

文章目录 1.模数转换器&#xff08;ADC&#xff09;是什么&#xff1f;手册说明&#xff1a; 2.STC32G单片机ADC使用原理19.1.1 ADC控制寄存器&#xff08;ADC_CONTR)19.1.2 ADC配置寄存器&#xff08;ADCCFG)19.1.4ADC时序控制寄存器&#xff08;ADCTIM&#xff09;19.3 ADC相…

网络安全第一次作业

1、什么是防火墙 防火墙是一种网络安全系统&#xff0c;它根据预先确定的安全规则监视和控制传入和传出的网络流量。其主要目的是阻止对计算机或网络的未经授权的访问&#xff0c;同时允许合法通信通过。 防火墙可以在硬件、软件或两者的组合中实现&#xff0c;并且可以配置为根…

嵌入式:驱动开发 Day9

作业&#xff1a;通过platform总线驱动实现 a.应用程序通过阻塞的io模型来读取number变量的值 b.number是内核驱动中的一个变量 c.number的值随着按键按下而改变&#xff08;按键中断&#xff09; 例如number0 按下按键number1 ,再次按下按键number0 d.在按下按键的时候需要同时…