Unity3D开发(二):NGUI Sprite在ScrollView下变灰方案

上期讲了在UIpanel.clipping != Clipping.SoftClip下按钮变灰的方案,但是当应用到SoftClip下时,会导致Sprite无法正常遮罩,而且变灰效果也消失的情况,例如ScrollView下,会导致上述问题。

因一时无从知晓到底哪里出现问题,于是便从ScrollView实现遮罩的方式入手,先了解下NGUI实现遮罩的方式,NGUI的渲染都是通过UIDrawCall类进行的,通过断点发现,当ScrollView进行遮罩时会在UIDrawCall的CreateMaterial()函数内进行动态换Shader操作:

if (panel.clipping == Clipping.TextureMask)
{

    mTextureClip = true;
    shader = Shader.Find("Hidden/" + shaderName +textureClip);
}
else if (mClipCount != 0)
{       
    shader = Shader.Find("Hidden/" + shaderName + " " + mClipCount);

    if (shader == null) shader = Shader.Find(shaderName + " " + mClipCount);
    // Legacy functionality
    if (shader == null && mClipCount == 1)
    {
        mLegacyShader = true;
        shader = Shader.Find(shaderName + soft);
        }
    }

通过上述代码可知,当为SoftClip状态下时,NGUI会自动给Sprite寻找名字为”Hidden/” + shaderName + ” ” + mClipCount的shader,显然,在Normal状态下,此时shader会变为NGUI自带的”Hidden/Unlit/Transparent Colored 1”,进入该shader后,我们会发现在frag()函数内有这么句代码col.a *= clamp( min(factor.x, factor.y), 0.0, 1.0);问题找到了,原来ScrollView是通过句代码来实现遮罩的,那么当我们将shader换成我们自己的shader时,首先在SoftClip下找不到一个叫”Hidden/xxxx 1”的shader进行替换,这时NGUI会强行换成默认状态的shader,因此,这就是导致我们上述问题的元凶。

替换为默认shader代码// Always fallback to the default shader
if (shader == null) shader = Shader.Find(“Unlit/Transparent Colored”)。

既然问题找到了,那么就可以着手解决这个问题了,首先仿照NGUI的shader,建立一个名叫”Hidden/UI/Sprite/Gray 1” 的shader,///注意此处shader命名需要与我第一篇的shader命名一致才可,即UI/Sprite/Gray处两个shader必须保持一致!!!!然后将”Hidden/Unlit/Transparent Colored 1”完全copy过来,最后在他的frag()函数内自行添加实现Sprite变灰的代码即可,这样在遮罩时就会找到正确的shader并替换,现在贴上我修改后的shader:

Shader "Hidden/UI/Sprite/Gray 1" 
{
    Properties
    {
        _MainTex ("Base (RGB), Alpha (A)", 2D) = "black" {}
    }

    SubShader
    {
        LOD 200

        Tags
        {
            "Queue" = "Transparent"
            "IgnoreProjector" = "True"
            "RenderType" = "Transparent"
        }

        Pass
        {
            Cull Off
            Lighting Off
            ZWrite Off
            Offset -1, -1
            Fog { Mode Off }
            ColorMask RGB
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float4 _ClipRange0 = float4(0.0, 0.0, 1.0, 1.0);
            float2 _ClipArgs0 = float2(1000.0, 1000.0);

            struct appdata_t
            {
                float4 vertex : POSITION;
                half4 color : COLOR;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : POSITION;
                half4 color : COLOR;
                float2 texcoord : TEXCOORD0;
                float2 worldPos : TEXCOORD1;
            };

            v2f o;

            v2f vert (appdata_t v)
            {
                o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                o.color = v.color;
                o.texcoord = v.texcoord;
                o.worldPos = v.vertex.xy * _ClipRange0.zw + _ClipRange0.xy;
                return o;
            }

            half4 frag (v2f IN) : COLOR
            {
                // Softness factor
                float2 factor = (float2(1.0, 1.0) - abs(IN.worldPos)) * _ClipArgs0;

                // Sample the texture
                half4 col = tex2D(_MainTex, IN.texcoord) * IN.color;
                col.rgb = dot(col.rgb, fixed3(.222,.707,.071));  
                col.a *= clamp( min(factor.x, factor.y), 0.0, 1.0);
                return col;
            }
            ENDCG
        }
    }

}

跟上一篇shader一样,通过 col.rgb = dot(col.rgb, fixed3(.222,.707,.071)); 实现变灰效果, col.a *= clamp( min(factor.x, factor.y), 0.0, 1.0);实现遮罩效果,现在两种效果合一,应该可以正常工作了,
下面上图这里写图片描述

可以看到正常工作,ok收工,下期开讲当ScrollView下有成百上千个item时优化工作,让滑动变得流畅。

你可能感兴趣的:(unity3d)