如何实现UGUI ScrollView底部边缘模糊效果?
UGUI ScrollView 滚动边缘渐变透明实现方法
你的思路有偏差,Mask是硬裁剪效果,无法实现渐变透明,下面是两种常用的实现方案:
方法一:自定义渐变遮罩Shader(推荐)
这种方式通过给ScrollView添加渐变遮罩层,实现边缘透明效果,步骤如下:
- 在ScrollView的Viewport节点下创建一个Image,与Content同级,大小和Viewport保持一致,取消勾选
Raycast Target避免影响滚动交互。 - 创建并使用以下自定义Shader,将其赋值给遮罩Image的Material:
Shader "UI/GradientMask" { Properties { [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} _Color ("Tint", Color) = (1,1,1,1) _TopY ("Top Gradient Y", Range(0,1)) = 0.1 _BottomY ("Bottom Gradient Y", Range(0,1)) = 0.9 _GradientStrength ("Gradient Strength", Range(0,1)) = 1 } SubShader { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" "CanUseSpriteAtlas"="True" } Cull Off Lighting Off ZWrite Off Blend SrcAlpha OneMinusSrcAlpha Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "UnityUI.cginc" struct appdata_t { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; float4 worldPosition : TEXCOORD1; }; fixed4 _Color; fixed4 _TextureSampleAdd; float _TopY; float _BottomY; float _GradientStrength; v2f vert(appdata_t v) { v2f o; o.worldPosition = v.vertex; o.vertex = UnityObjectToClipPos(o.worldPosition); o.texcoord = v.texcoord; o.color = v.color * _Color; return o; } sampler2D _MainTex; fixed4 frag(v2f i) : SV_Target { fixed4 col = (tex2D(_MainTex, i.texcoord) + _TextureSampleAdd) * i.color; // 计算Y轴位置的渐变alpha float y = i.worldPosition.y / _ScreenParams.y; float alpha = 1; if(y < _TopY) { alpha = smoothstep(0, _TopY, y) * _GradientStrength; } else if(y > _BottomY) { alpha = smoothstep(1, _BottomY, y) * _GradientStrength; } col.a *= alpha; return col; } ENDCG } } }
- 调整Material的参数:
_TopY控制顶部渐变起始位置,_BottomY控制底部渐变起始位置,_GradientStrength控制渐变透明度强度,直到匹配图中效果。
方法二:滚动监听动态调整元素透明度
适合元素数量较少的场景,通过监听滚动值修改Content内元素的透明度:
- 创建以下C#脚本,挂载到ScrollView节点上:
using UnityEngine; using UnityEngine.UI; public class ScrollGradient : MonoBehaviour { public ScrollRect scrollRect; public float gradientRange = 100; // 渐变影响的高度范围 private RectTransform viewportRect; private RectTransform contentRect; void Start() { viewportRect = scrollRect.viewport as RectTransform; contentRect = scrollRect.content as RectTransform; scrollRect.onValueChanged.AddListener(OnScrollChanged); OnScrollChanged(scrollRect.verticalNormalizedPosition); } void OnScrollChanged(Vector2 scrollPos) { float viewportHeight = viewportRect.rect.height; float contentOffset = contentRect.anchoredPosition.y; foreach (Transform child in contentRect) { if (!(child is RectTransform childRect)) continue; float childBottom = childRect.anchoredPosition.y + childRect.rect.yMin; float childTop = childRect.anchoredPosition.y + childRect.rect.yMax; float visibleBottom = contentOffset; float visibleTop = contentOffset + viewportHeight; float alpha = 1; if (childTop > visibleTop) { float overTop = childTop - visibleTop; alpha = Mathf.Clamp01(1 - overTop / gradientRange); } else if (childBottom < visibleBottom) { float overBottom = visibleBottom - childBottom; alpha = Mathf.Clamp01(1 - overBottom / gradientRange); } if (child.TryGetComponent(out Graphic graphic)) { Color color = graphic.color; color.a = alpha; graphic.color = color; } } } }
- 在Inspector面板中赋值
scrollRect引用,调整gradientRange参数控制渐变的高度范围,运行后即可看到滚动时元素边缘渐变透明的效果。
内容的提问来源于stack exchange,提问作者Bak
相关产品推荐
相关产品推荐

