在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_ONfloat 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;}*///判断方法2if (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 源文件,以及实例工程如下链接
示例工程文件