【Unity】粒子特效与Scroll View滑动显示问题

【Unity】粒子特效与Scroll View滑动显示问题_第1张图片
在做背包、商城等界面的时候不管是NGUI还是UGUI,都会遇到特效在格子上滑动后特效不会隐藏这种问题
【Unity】粒子特效与Scroll View滑动显示问题_第2张图片
我的解决方法是利用shader可以实现剔除的效果

  1. 求出容器的边界
  2. 把边界传给每一个条目的shader
  3. 判断顶点坐标是否超出边界坐标,把超出的部分透明度设为0
    private Transform content;
    private Transform m_canvas;
    private RectTransform m_rectTrans; //容器的rect
    private float m_halfWidth;
    private float m_halfHeight;
    ParticleSystem[] particles;

    void Start()
    {
        m_canvas = GameObject.Find("Canvas").transform;
        content = gameObject.transform.Find("Viewport/Content");

        particles = content.GetComponentsInChildren<ParticleSystem>();
        m_rectTrans = gameObject.GetComponent<RectTransform>();

        //计算容器宽高的一半,值得注意的是要乘cnavas的缩放比例
        m_halfWidth = m_rectTrans.sizeDelta.x * 0.5f * m_canvas.localScale.x;
        m_halfHeight = m_rectTrans.sizeDelta.y * 0.5f * m_canvas.localScale.x;

        Vector4 area = CalculateArea(m_rectTrans.position);

        foreach (var item in particles)
        {
            //给Shader _Area属性赋值
            item.GetComponent<Renderer>().material.SetVector("_Area", area);
        }
    }

    //计算容器在世界坐标的Vector4,xz为左右边界的值,yw为下上边界值
    Vector4 CalculateArea(Vector3 position)
    {
        return new Vector4()
        {
            x = position.x - m_halfWidth,
            y = position.y - m_halfHeight,
            z = position.x + m_halfWidth,
            w = position.y + m_halfHeight
        };
    }

【Unity】粒子特效与Scroll View滑动显示问题_第3张图片
如果使用UICamer的话scale会改变,所以要得到世界坐标需要乘scale的缩放比例

 //计算容器宽高的一半,值得注意的是要乘cnavas的缩放比例
 m_halfWidth = m_rectTrans.sizeDelta.x * 0.5f * m_canvas.localScale.x;
 m_halfHeight = m_rectTrans.sizeDelta.y * 0.5f * m_canvas.localScale.x;

Shader部分
shader代码不难理解,就是对顶点做一个边界判断
_Area.xz代表上边和下边的y
_Areayw代表左边和右边的x

Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        [HDR]_Color("Color",color) = (1,1,1,1)
        _Area("Area",Vector) = (0,0,0,0)
    }
    SubShader
    {
        Tags{"RenderType" = "Transparent"  "Queue" = "Transparent"}
        Blend srcalpha OneMinusSrcAlpha


        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;

            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float2 worldPos : TEXCOORD1;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                //把顶点坐标转为世界坐标
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xy;
                return o;
            }

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float4 _Area;
            fixed4 _Color;

            fixed4 frag (v2f i) : SV_Target
            {
                //计算边界值
                bool inArea = i.worldPos.x >= _Area.x && i.worldPos.x <= _Area.z && i.worldPos.y >= _Area.y && i.worldPos.y <= _Area.w;
                //超出边界部分的颜色透明
                return inArea ? tex2D(_MainTex, i.uv) * _Color : fixed4(0, 0, 0, 0);
            }
            ENDCG
        }
    }

最终效果
【Unity】粒子特效与Scroll View滑动显示问题_第4张图片

你可能感兴趣的:(【Unity】粒子特效与Scroll View滑动显示问题)