如何为2D正方形添加从上到下的半透明渐变效果?
实现Unity UI正方形顶部不透明、底部半透明的方法
你当前的代码是对整个Image的color属性进行插值,这会让整个正方形的颜色/透明度统一变化,无法实现顶部和底部区域独立的透明度差异。要实现垂直方向的渐变效果,需要针对UI元素的顶点或纹理做渐变处理,以下是几种可行方案:
方案1:使用自定义渐变纹理
创建一个垂直渐变的纹理,顶部为不透明颜色,底部为半透明颜色,将其作为Image的Sprite使用:
using UnityEngine; using UnityEngine.UI; public class GradientTextureCreator : MonoBehaviour { public Color topColor = Color.white; public Color bottomColor = new Color(1,1,1,0.5f); private Image _image; void Start() { _image = GetComponent<Image>(); // 创建2x2的渐变纹理(足够实现垂直渐变) Texture2D gradientTex = new Texture2D(2, 2); gradientTex.SetPixel(0, 1, topColor); gradientTex.SetPixel(1, 1, topColor); gradientTex.SetPixel(0, 0, bottomColor); gradientTex.SetPixel(1, 0, bottomColor); gradientTex.Apply(); // 创建Sprite并赋值给Image Sprite gradientSprite = Sprite.Create(gradientTex, new Rect(0,0,gradientTex.width,gradientTex.height), new Vector2(0.5f,0.5f)); _image.sprite = gradientSprite; _image.type = Image.Type.Sliced; // 确保拉伸时渐变保持正确方向 } }
方案2:自定义UI渐变Shader
编写一个简单的UI Shader,支持垂直方向的颜色渐变,将其赋值给Image的Material:
Shader代码(保存为UI_Gradient.shader):
Shader "UI/Gradient" { Properties { [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} _Color ("Tint", Color) = (1,1,1,1) _TopColor ("Top Color", Color) = (1,1,1,1) _BottomColor ("Bottom Color", Color) = (1,1,1,0.5f) _StencilComp ("Stencil Comparison", Float) = 8 _Stencil ("Stencil ID", Float) = 0 _StencilOp ("Stencil Operation", Float) = 0 _StencilWriteMask ("Stencil Write Mask", Float) = 255 _StencilReadMask ("Stencil Read Mask", Float) = 255 _ColorMask ("Color Mask", Float) = 15 } SubShader { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" "CanUseSpriteAtlas"="True" } Stencil { Ref [_Stencil] Comp [_StencilComp] Pass [_StencilOp] ReadMask [_StencilReadMask] WriteMask [_StencilWriteMask] } Cull Off Lighting Off ZWrite Off ZTest [unity_GUIZTestMode] Blend SrcAlpha OneMinusSrcAlpha ColorMask [_ColorMask] 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; }; sampler2D _MainTex; fixed4 _Color; fixed4 _TopColor; fixed4 _BottomColor; fixed4 _TextureSampleAdd; float4 _ClipRect; 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; } fixed4 frag(v2f i) : SV_Target { // 基于顶点的y坐标(0到1)进行颜色插值 float lerpValue = i.worldPosition.y; fixed4 gradientColor = lerp(_BottomColor, _TopColor, lerpValue); fixed4 col = (tex2D(_MainTex, i.texcoord) + _TextureSampleAdd) * i.color * gradientColor; col.a = UnityGet2DClipping(i.worldPosition.xy, _ClipRect) * col.a; return col; } ENDCG } } }
使用方法:
- 创建一个新的Material,将Shader设置为
UI/Gradient - 调整
Top Color和Bottom Color的参数(顶部设为不透明,底部设为半透明) - 将这个Material赋值给你的UI Image组件
方案3:通过顶点颜色实现渐变
直接修改UI Image的顶点颜色,实现垂直渐变效果:
using UnityEngine; using UnityEngine.UI; [RequireComponent(typeof(Image))] public class UIVerticalGradient : MonoBehaviour { public Color topColor = Color.white; public Color bottomColor = new Color(1,1,1,0.5f); private Image _image; void Start() { _image = GetComponent<Image>(); UpdateGradient(); } void UpdateGradient() { if (_image == null || _image.sprite == null) return; // 获取Image的顶点数组 VertexHelper vh = new VertexHelper(); _image.PopulateMesh(vh); UIVertex[] vertices = new UIVertex[4]; vh.GetUIVertexStream(vertices); // 顶部两个顶点设为topColor,底部两个设为bottomColor vertices[0].color = bottomColor; vertices[1].color = topColor; vertices[2].color = topColor; vertices[3].color = bottomColor; // 重新赋值顶点数据 vh.Clear(); vh.AddUIVertexQuad(vertices); _image.canvasRenderer.SetMesh(vh.mesh); } // 如果需要动态修改颜色,可以调用这个方法 public void SetGradientColors(Color top, Color bottom) { topColor = top; bottomColor = bottom; UpdateGradient(); } }
内容的提问来源于stack exchange,提问作者IgnaVilla Urb
相关产品推荐
相关产品推荐

