You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 16:11:15