目录:粒子裁剪、粒子和遮罩贴合
- 最终效果
- 裁剪shader
- 粒子配置
- shader
- 粒子裁剪
- 效果
- 布局
- 脚本
- 粒子和遮罩贴合
最终效果
裁剪shader
粒子配置
shader
Shader "Custom/Particle Clipping"
{
Properties
{
_MinX ("Min X", float) = 0
_MinY ("Min Y", float) = 0
_MaxX ("Max X", float) = 0
_MaxY ("Max Y", float) = 0
_Color ("Color", Color) = (0, 0, 0, 0)
_MainTex ("MainTex", 2D) = "white" {}
}
SubShader
{
Tags
{
"Queue" = "Transparent" // 透明队列
"IngnoreProjector" = "True" // 忽略阴影
"RenderType" = "Transparent" // 渲染类型
}
Pass
{
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma
#pragma
float _MinX;
float _MinY;
float _MaxX;
float _MaxY;
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
struct a2v
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
fixed4 color : COLOR;
};
v2f vert(a2v v)
{
v2f f;
f.pos = UnityObjectToClipPos(v.vertex);
f.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
f.color = v.vertex;
return f;
}
fixed4 frag(v2f f) : SV_Target
{
fixed4 color = tex2D(_MainTex, f.uv);
// 判断是否在区域内
color.a *= f.color.x >= _MinX;
color.a *= f.color.x <= _MaxX;
color.a *= f.color.y >= _MinY;
color.a *= f.color.y <= _MaxY;
color.rgb *= color.a;
return color + _Color;
// 判断是否在区域内(Shader中使用if...else来做判断影响效率,不建议使用)
// const bool is_area = f.color.x >= _MinX && f.color.x <= _MaxX && f.color.y >= _MinY && f.color.y <= _MaxY;
// return is_area ? color : fixed4(0,0,0,0);
}
ENDCG
}
}
FallBack "Diffuse"
}
粒子裁剪
效果
布局
脚本
using UnityEngine;
using UnityEngine.UI;
[DisallowMultipleComponent] // 防止将相同类型(或子类型)的 MonoBehaviour 多次添加到 GameObject
[RequireComponent(typeof(Image))] // RequireComponent 属性自动将所需的组件添加为依赖项
[AddComponentMenu("UI/UISuperMask")] // 使用 AddComponentMenu 属性可在“Component”菜单中的任意位置放置脚本,而不仅是“Component > Scripts”菜单
public class UISuperMask : Mask
{
// 左下 左上 右上 右下
private readonly Vector3[] _corners = new Vector3[4];
private float _minX = 0f, _minY = 0f, _maxX = 0f, _maxY = 0f;
void GetMaskWorldCorners()
{
RectTransform target = transform as RectTransform;
target!.GetWorldCorners(_corners);
_minX = _corners[0].x;
_minY = _corners[0].y;
_maxX = _corners[2].x;
_maxY = _corners[2].y;
}
protected override void OnRectTransformDimensionsChange()
{
if (Application.isPlaying)
{
GetMaskWorldCorners();
foreach (ParticleSystemRenderer particle in transform.GetComponentsInChildren<ParticleSystemRenderer>(true))
{
SetRenderer(particle);
}
}
}
private void SetRenderer(Renderer renderer)
{
if (renderer.sharedMaterial)
{
Material material = renderer.material;
material.SetFloat("_MinX", _minX);
material.SetFloat("_MinY", _minY);
material.SetFloat("_MaxX", _maxX);
material.SetFloat("_MaxY", _maxY);
}
}
}
粒子和遮罩贴合
新增一个UICamera游戏对象,添加到Canvas上
粒子采用默认配置并添加 Material 即可