在UGUI开发中 会遇到以下情况,scrollview 下面有item附带粒子特效(道具选中特效)由于UGUI内置的Mask 裁剪不了 粒子
,所以有以下解决方案
在粒子特效物体上使用新的shader 如下
在合适的物体上挂载TailorParticle .cs代码
public class TailorParticle : MonoBehaviour
{
private Material material;
private Mask mask;
public void Start()
{
material = GetComponentInChildren<ParticleSystem>().GetComponent<Renderer>().material;
mask = GetComponentInParent<Mask>();
SetClip();
//如果运行时裁剪区域不会发生改变,可以注释掉下面这句代码
GetComponentInParent<ScrollRect>().onValueChanged.AddListener(v => { SetClip(); });
}
public void SetClip()
{
//获取到需要裁剪的区域
Vector3[] corners = new Vector3[4];
mask.GetComponent<RectTransform>().GetWorldCorners(corners);
//将裁剪区域传入到Shader中
material.SetFloat("_MinX", corners[0].x);
material.SetFloat("_MinY", corners[0].y);
material.SetFloat("_MaxX", corners[2].x);
material.SetFloat("_MaxY", corners[2].y);
}
}
原理是:在原有粒子特效的加一个float4变量 挂载的cs监本将滑动时的裁剪区域传给shader,在shader 中判断超出mask裁剪区域的颜色.a = 0 (即透明)
frag函数部分:
fixed4 frag (v2f i) : SV_Target
{
#ifdef SOFTPARTICLES_ON
float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)));
float partZ = i.projPos.z;
float fade = saturate (_InvFade * (sceneZ-partZ));
i.color.a *= fade;
#endif
//-------------------add----------------------
fixed4 c =2.0f * i.color * _TintColor * tex2D(_MainTex, i.texcoord);
//判断方法1
/*if (i.vpos.x >= _MinX && i.vpos.x <= _MaxX && i.vpos.y >= _MinY&& i.vpos.y <= _MaxY)
{
c.a *= 1;
}
else
{
c.a *= 0;
}*/
//判断方法2
if (UnityGet2DClipping(i.vpos.xy, float4(_MinX, _MinY,_MaxX, _MaxY)))
{
c.a *= 1;
}
else
{
c.a *= 0;
}
//判断方法3
/*
c.a *= (i.vpos.x >= _MinX );
c.a *= (i.vpos.x <= _MaxX);
c.a *= (i.vpos.y >= _MinY);
c.a *= (i.vpos.y <= _MaxY);
c.rgb *= c.a;
*/
return c;
//-------------------add----------------------
}
新的shader 源文件,以及实例工程如下链接
示例工程文件
下载的童鞋用2019打开 不然会发现引用丢失0-0