【游戏开发实战】Unity使用ShaderGraph制作一个Loading水球(能量球 | UI | 2D | 特效 | URP)
时间:2022-12-31 14:30:00
文章目录
-
-
- 一、前言
- 二、ShaderGraph入门
- 三、ShaderGraph制作2D Loading水球
-
- 1、创建Unlit Shader Graph
- 创造一个圆
- 3.自下而上填充的效果
- 4.填充效果与圆相乘
- 5.填充边界波浪效果
- 6、水球颜色
- 7.输出到片元着色器
- 再加一点细节
- 四、应用到UI上
-
- 1、界面UI
- 2.制作材料球
- 3.脚本控制进度
- 4、运行效果
- 五、工程源码
-
本文的最终结果
一、前言
大家好,我是林新发。
有同学私信问我怎么办2D
水球的效果,
事实上,我看到有人在网上写了相应的教程。今天让我们一起做一个~
二、ShaderGraph入门
我以前写过一篇文章:《ShaderGraph使用教程和各种特效案例:Unity2020(持续更新)
也许可以作为大家的入门ShaderGraph
的参考
本文直接进入Graph
节点生产环境~
三、ShaderGraph制作2D Loading水球
注:我用过这篇文章Unity
版本为2021.1.9f1c1
,Universal RP
版本为11.0.0
,如果你使用的版本与我不同,可能会略有差别
1、创建Unlit Shader Graph
我们要做的是2D
不需要光,所以我们创造了一个Unlit Shader Graph
,
取名叫LoadingBall
好了,
2、创建一个圆
ShaderGraph
节点中,在Procedural/Shape
几何图形节点到几何图形节点,如下
我们创造了一个圆(Ellipse
节点),
注:
Ellipse
意思是椭圆,当Width
和Height
当你想要一个圆的时候,它是一个圆,而不是搜索Circle
,而是搜索Ellipse
哦~
接一个Slider
,大小调整方便,
3.自下而上填充的效果
思考:如何表达图片从下到上填充的效果?
我们分为两个问题:
1.纹理坐标上下左右用什么来表达?
如何表达填充效果的上下边界?
首先回答第一个问题。在纹理坐标中,我们使用它UV坐标系
,U
和V
的值范围是 0 ~ 1
,画个图,
通过UV
坐标,我们可以采样纹理的任何像素,所以,我们想从左到右表达,实际上是U
从0
到 1
,如果你想从下到上表达,那就是V
从0
到1
。
在ShaderGraph
中,有个UV
我们可以通过它访问节点U
和V
了,
因为我们想要的是从下到上,我们只需要V
轴的信息,我们可以使用Split
把UV
分离后,U
的值对应Split
的R
,V
的值对应Slplit
的G
,所以们把G
取出来,使用Preview
节点预览一下,
到这里,我们就得到了V
从 0
到 1
的效果了,
现在解决第二个问题,上下部分的边界怎么表达?
这个问题,首先要明白边界是什么,边界就是一个阈值,比如上面我们 0
到 1
这个范围,我定义 0.35
为阈值,比它小的表示边界以下,比它大的表示边界以上。
在ShaderGraph
中如何表达呢?这里就要用到Step
节点了,我们新建一个Step
节点,
当In
大于等于Edge
时,Step
输出1
,否则输出0
,
我们把刚刚的V
值作为Step
的Eedge
,然后使用一个Slider
作为In
,也就是说我们把In
作为上下边界的阈值,我们通过In
就可以控制边界了。
如下,这样我们就表现出从下到上填充的效果了
4、填充效果与圆相乘
我们把第3
步得到的填充效果与第2
步的圆相乘,即可得到一个填充圆的效果啦~
5、填充边界波浪效果
上面的边界效果是平平的,没有波浪起伏的效果,现在我们要给这个边界制作一个波浪起伏的效果。
换句话说,我们要给Step
的In
做一个扰动,做扰动第一个想到的就是噪声,在ShaderGraph
中,噪声有好几种,
大家根据需求选择,这里我使用Gradient Noise
噪声,
我们把把噪声与Slider
相加,可以看到扰动颗粒过细了,导致边界被撕裂了,
我们可以调整噪声的Scale
,如下
我们要让边界水平动起来,我们可以给噪声UV
的V
加一个随时间变化的Offset
,用到Time
和Till And Offset
节点,
不过我们看到现在水面波动幅度过大,
我们可以给噪声做一个Remap
,把它的强度减弱,
此时波浪就温柔很多了,
到此,一个水球的雏形就出来了,
6、水球颜色
我们给水球加一个颜色,创建一个Color
节点,与水球相乘,如下,
7、输出到片元着色器
把水球输出到Fragment
(片元着色器)的Base Color
上,另外通过Alpha Clip Threshold
来做透明度剔除,如下,
注意Graph Settings
中要开启Alpha Clip
,规则是当Alpha
大于Alpha Clip Threshold
时显示像素,否则抛弃像素,从而得到Mask
的效果,
8、再加一点点细节
最后,我们再加一点点细节,最终节点结构如下
预览一下效果,
四、应用到UI上
1、界面UI
我们使用UGUI
制作一下简单的UI
,其中,使用Image
来显示水球,
因为现在还没有使用材质球,所以Image
是一个白色的方块,
2、制作材质球
我们创建一个材质球,命名为LoadingBall
,并让它使用上面的ShaderGraph
,
如下
把材质球赋值给Image
,
此时界面效果如下,
3、脚本控制进度
我们简单写个脚本做一下进度控制,代码如下
using UnityEngine;
using UnityEngine.UI;
public class LoadingBall : MonoBehaviour
{
[Range(0, 1)]
public float progress = 0.5f;
public Material mat;
public Text progressText;
private int propertyProgressID;
void Start()
{
propertyProgressID = Shader.PropertyToID("progress");
}
void Update()
{
mat.SetFloat(propertyProgressID, progress);
progressText.text = $"{
Mathf.Floor(progress * 100)}%";
}
}
其中我在ShaderGraph
中把进度值的属性名命名为progress
,代码中使用Shader.PropertyToID("progress")
得到属性ID
,再通过Material
的SetFloat
方法冬天修改属性值,
把LoadingBall
脚本挂到水球的Image
节点上,并赋值成员变量,如下,
4、运行效果
运行效果如下,
五、工程源码
本文工程源码我已上传到GitCode
,感兴趣的同学可自行下载学习,
项目地址:https://gitcode.net/linxinfa/UnityLoadingBallSG
注:本文我使用的Unity
版本为2021.1.9f1c1
,Universal RP
版本为11.0.0
,如果你使用的版本与我不同,可能会略有差别
好了,我是林新发,https://blog.csdn.net/linxinfa
一个在小公司默默奋斗的Unity
开发者,希望可以帮助更多想学Unity
的人,共勉~