Unity3D UI遮罩和弹窗

12 篇文章 1 订阅
2 篇文章 0 订阅

详细讲解篇幅可能有点长,直接上图和资源(实现的具体步骤往下看)

GIF图看起来有点卡顿, 实际上运行是流畅的。

码云:https://gitee.com/NCAA_admin/Alert.git

具体实现步骤

1.创建一个背景图片Background并设置相应属性值

2.设置Canvas的属性和Game窗口的比例

3.创建一个弹窗的遮罩蒙版 名为Alert的Image,参数设置如下

4.在Alert下创建一个弹出的信息框 名为Message的Image,各参数设置如下

5.在Message下创建一个文本对象 Text,参数设置如下

6.接在也在Alert下创建两个按钮 Confirm和Cancel

7.其中两个按钮的Text参数分别如下

8.创建一个Shader的蒙版,在Assets下创建Shaders文件夹,在Shaders文件夹下创建名为Blur的Shader脚本

10.Shader脚本,内容如下(关于Shader的实现原理和步骤,有时间再做一个专题的解析)

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/Blur"
{
	// 属性
	Properties
	{
		// 定义 1-255 范围的半径 默认 1
		_Radius("Radius", Range(1, 255)) = 1
	}

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

		SubShader
	{

	GrabPass
	{
		Tags{ "LightMode" = "Always" }
	}

	Pass
	{
		Tags{ "LightMode" = "Always" }
		
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#pragma fragmentoption ARB_precision_hint_fastest
		#include "UnityCG.cginc"

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

	struct v2f
	{
		float4 vertex : POSITION;
		float4 uvgrab : TEXCOORD0;
	};

	v2f vert(appdata_t v)
	{
		v2f o;
		o.vertex = UnityObjectToClipPos(v.vertex);
#if UNITY_UV_STARTS_AT_TOP
		float scale = -1.0;
#else
		float scale = 1.0;
#endif
		o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
		o.uvgrab.zw = o.vertex.zw;
		return o;
	}

	sampler2D _GrabTexture;
	float4 _GrabTexture_TexelSize;
	float _Radius;

	half4 frag(v2f i) : COLOR
	{
		half4 sum = half4(0,0,0,0);

#define GRABXYPIXEL(kernelx, kernely) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely, i.uvgrab.z, i.uvgrab.w)))

		sum += GRABXYPIXEL(0.0, 0.0);
		int measurments = 1;

		for (float range = 0.1f; range <= _Radius; range += 0.1f)
		{
			sum += GRABXYPIXEL(range, range);
			sum += GRABXYPIXEL(range, -range);
			sum += GRABXYPIXEL(-range, range);
			sum += GRABXYPIXEL(-range, -range);
			measurments += 4;
		}

		return sum / measurments;
	}
		ENDCG
	}
		GrabPass
	{
		Tags{ "LightMode" = "Always" }
	}

		Pass
	{
		Tags{ "LightMode" = "Always" }

		CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"

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

	struct v2f
	{
		float4 vertex : POSITION;
		float4 uvgrab : TEXCOORD0;
	};

	v2f vert(appdata_t v)
	{
		v2f o;
		o.vertex = UnityObjectToClipPos(v.vertex);
#if UNITY_UV_STARTS_AT_TOP
		float scale = -1.0;
#else
		float scale = 1.0;
#endif
		o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
		o.uvgrab.zw = o.vertex.zw;
		return o;
	}

	sampler2D _GrabTexture;
	float4 _GrabTexture_TexelSize;
	float _Radius;

	half4 frag(v2f i) : COLOR
	{

		half4 sum = half4(0,0,0,0);
		float radius = 1.41421356237 * _Radius;

#define GRABXYPIXEL(kernelx, kernely) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely, i.uvgrab.z, i.uvgrab.w)))

		sum += GRABXYPIXEL(0.0, 0.0);
		int measurments = 1;

		for (float range = 1.41421356237f; range <= radius * 1.41; range += 1.41421356237f)
		{
			sum += GRABXYPIXEL(range, 0);
			sum += GRABXYPIXEL(-range, 0);
			sum += GRABXYPIXEL(0, range);
			sum += GRABXYPIXEL(0, -range);
			measurments += 4;
		}

		return sum / measurments;
	}
		ENDCG
	}
	}
	}
}

11.在Assets下创建一个名Materials文件夹,在Materials文件夹下创建名为MaskBlur的Material材质

12.在Alert下指定MaskBlur材质,并设置材质的模糊值为5

13.为了使交互效果具有动画的过度感,在编辑器顶部的菜单栏中 Windows>Asset Store 下打开资源商店

14.搜索DoTween关键词,并进入下载

15.下载完成后点击导入即可

16.在Assets下创建Scripts文件夹,在Scripts下创建Alert.cs脚本

17.Alert.cs脚本内容

using UnityEngine;
using DG.Tweening;
using UnityEngine.UI;
using UnityEngine.EventSystems;
//显示Alert会话
public class Alert : MonoBehaviour
{
    public static Alert Instance;
    private void Awake()
    {
        Instance = this;
    }
    [Tooltip("会话对象")] public RectTransform m_alert;
    //获取ui blur(alert)初始大小
    private Vector2 _uiBlurSize;
    //获取ui blur(alert)初始scale
    private Vector2 _uiBlurScale;
    //透明遮罩层
    private RectTransform _transparentMask;
    //透明遮罩层的初始颜色值值
    private Color _transparentMaskColor;
    //获取confirm
    private RectTransform _confirm;
    //获取confirm初始大小
    private Vector2 _confirmSize;
    //获取confirm初始scale
    private Vector2 _confirmScale;
    //获取text对象
    private Text _text;
    //获取text的大小
    private Vector2 _textSize;
    //获取text scale
    private Vector2 _textScale;
    void Start()
    {
        //判断并且赋值
        if (!m_alert)
        {
            m_alert = transform.GetComponent<RectTransform>();
        }
        //获取uiblur(alert)初始大小
        _uiBlurSize = m_alert.rect.size;
        _uiBlurScale = m_alert.localScale;
        //获取透明遮罩层
        _transparentMask = m_alert.GetChild(0).GetComponent<RectTransform>();
        //透明遮罩层的颜色
        _transparentMaskColor = _transparentMask.GetComponent<Image>().color;
        //获取confirm
        _confirm = m_alert.GetChild(1).GetComponent<RectTransform>();
        //获取confirm初始大小
        _confirmSize = _confirm.rect.size;
        _confirmScale = _confirm.localScale;
        //获取text对象
        _text = _confirm.GetChild(0).GetComponent<Text>();
        //获取text的大小
        _textSize = _text.GetComponent<RectTransform>().rect.size;
        _textScale = _text.rectTransform.localScale;
        //确定取消按钮
        _Confirm();
        _Cancel();
        //初始设置隐藏
        if (m_hideOnStart)
            _SetHideImmediate();
    }

    /// <summary>
    /// 无动画立即隐藏
    /// </summary>
    public void _SetHideImmediate()
    {
        //设置隐藏
        m_alert.gameObject.SetActive(false);
        _confirm.gameObject.SetActive(false);
        _text.gameObject.SetActive(false);
        _transparentMask.gameObject.SetActive(false);
        //宽高设置0
        m_alert.DOScale(Vector3.zero, 0);
        _confirm.DOScale(Vector3.zero, 0);
        //设置遮罩层alpha = 0
        _transparentMask.GetComponent<Image>().DOFade(0, 0);
    }
    /// <summary>
    /// 开始时为隐藏状态
    /// </summary>
    [Tooltip("开始时为隐藏状态")]
    public bool m_hideOnStart = true;
    /// <summary>
    /// 隐藏
    /// </summary>
    public void _SetHide()
    {
        //设置隐藏
        _text.gameObject.SetActive(false);
        //宽高设置0
        m_alert.DOScale(Vector2.zero, _SetShow_duration)
            .onComplete = () =>
            {
                m_alert.gameObject.SetActive(false);
            };
        _confirm.DOScale(Vector2.zero, _SetShow_duration)
            .onComplete = () =>
            {
                _confirm.gameObject.SetActive(false);
            };
        //隐藏透明遮罩层
        _transparentMask.GetComponent<Image>().DOFade(0, _SetShow_duration)
            .onComplete = () =>
            {
                _transparentMask.gameObject.SetActive(false);
            };
    }
    /// <summary>
    /// 显示
    /// </summary>
    public void _SetShow()
    {
        //设置显示
        m_alert.gameObject.SetActive(true);
        _confirm.gameObject.SetActive(true);
        _transparentMask.gameObject.SetActive(true);
        //宽高设置成初始大小+5%再回到原来的大小
        m_alert.DOScale(_uiBlurScale + _uiBlurScale * 0.05f, _SetShow_duration)
            .onComplete = () =>
            {
                //完成后回到初始大小 时间为原来的1/5
                m_alert.DOScale(_uiBlurScale, _SetShow_duration / 5f);
            };
        _confirm.DOScale(_confirmScale + _confirmScale * 0.05f, _SetShow_duration)
            .onComplete = () =>
            {
                //完成后回到初始大小 时间为原来的1/5
                _confirm.DOScale(_confirmScale, _SetShow_duration / 5f);
                //并且显示text
                _text.gameObject.SetActive(true);
            };
        //显示透明遮罩层
        _transparentMask.GetComponent<Image>().DOFade(_transparentMaskColor.a, _SetShow_duration);
    }
    /// <summary>
    /// 显示动画时间
    /// </summary>
    private float _SetShow_duration = 0.3f;

    /// <summary>
    /// 按钮的hover效果
    /// </summary>
    /// <param name="button">按钮</param>
    public void _OnHover(Transform button)
    {
        if (!m_inited)
        {
            m_inited = true;
            //获取初始大小
            m_initialScale = transform.GetComponent<RectTransform>().localScale.x;
        }
        if (!button.GetComponent<EventTrigger>()) button.gameObject.AddComponent<EventTrigger>();
        EventTrigger trigger = button.GetComponent<EventTrigger>();
        EventTrigger.Entry entry = new EventTrigger.Entry();
        entry.eventID = EventTriggerType.PointerEnter;
        entry.callback = new EventTrigger.TriggerEvent();
        entry.callback.AddListener(delegate (BaseEventData baseEvent) {
            button.GetComponent<RectTransform>().DOScale(m_localScale, 0.3f);
        });
        trigger.triggers.Add(entry);

        EventTrigger.Entry entry2 = new EventTrigger.Entry();
        entry2.eventID = EventTriggerType.PointerExit;
        entry2.callback = new EventTrigger.TriggerEvent();
        entry2.callback.AddListener(delegate (BaseEventData baseEvent) {
            button.GetComponent<RectTransform>().DOScale(m_initialScale, 0.3f);
        });
        trigger.triggers.Add(entry2);
    }
    /// <summary>
    /// 变大尺度默认1
    /// </summary>
    [Tooltip("变大尺度默认1.2f")]
    public float m_localScale = 1.2f;
    /// <summary>
    /// 初始的大小
    /// </summary>
    private float m_initialScale;
    /// <summary>
    /// 是否被初始化
    /// </summary>
    private bool m_inited = false;

    /// <summary>
    /// 确定
    /// </summary>
    public void _Confirm()
    {
        _OnHover(m_confirm);
        m_confirm.GetComponent<Button>().onClick.AddListener(delegate {
            _SetHide();
        });
    }
    /// <summary>
    /// 确定按钮
    /// </summary>
    [Tooltip("确定按钮")]
    public Transform m_confirm;
    /// <summary>
    /// 取消按钮
    /// </summary>
    public void _Cancel()
    {
        _OnHover(m_cancel);
        m_cancel.GetComponent<Button>().onClick.AddListener(delegate {
            _SetHide();
        });
    }
    [Tooltip("取消按钮")]
    public Transform m_cancel;

}

18.将Alert.cs脚本拖拽到Alert对象上,并分别将Confirm和Cancel对象拖拽到Alert对应的组件上

19.再在Assets>Scripts文件夹下新建键盘事件的脚本 KeyEvent.cs

20.KeyEvent.cs脚本内容

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class KeyEvent : MonoBehaviour
{
    /// <summary>
    /// 获取Alert组件
    /// </summary>
    private Alert alert;
    void Start()
    {
        //实例化组件
        alert = Alert.Instance;
    }

    void Update()
    {
        //键盘事件
        _KeyDown();
    }

    /// <summary>
    /// 按下键盘执行
    /// </summary>
    public void _KeyDown()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            alert._SetShow();
        }
    }

}

21.在Hierarchy下新建一个脚本管理器的空物体Script,并将KeyEvent.cs脚本附在其上

22.为了让Hierarchy下的组件的层次更加明显,分别新建了三个空物体,具体如下

23.最后运行游戏,按下Esc键弹出信息框

结束:GIF效果图请看文章顶部!

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Unity 3D中实现模型半透明遮罩可以通过以下步骤: 第一步是在Shader中使用透明度。可以创建一个新的材质,并将其Shader设置为透明度。 根据模型的需求,可以设置不同的透明度值。透明度为1表示完全不透明,透明度为0表示完全透明。 第二步是将半透明材质应用到模型上。在Unity中,可以选择需要添加材质的模型,并将其属性面板的材质设置为步骤一中创建的半透明材质。 第三步是设置模型的深度缓冲区(Depth Buffer)测试。深度缓冲区用于确定模型之间的绘制顺序。在半透明效果中,正确的深度缓冲区测试可以避免模型之间的遮挡问题。在Unity中,可以通过调整Camera组件的Depth Texture Mode和Depth写入设置来实现。 第四步是调整渲染队列(Render Queue)顺序。渲染队列用于确定渲染对象的绘制顺序,这对于半透明遮罩效果非常关键。可以通过修改Shader中的“Queue”指令来调整渲染队列顺序,将半透明材质的渲染队列指定为适当的值,确保其在其他不透明对象之后绘制。 使用以上步骤,可以在Unity 3D中实现模型的半透明遮罩效果。通过调整透明度、深度缓冲区测试和渲染队列顺序,可以实现不同类型的半透明遮罩效果,为游戏或应用程序增添视觉上的吸引力。 ### 回答2: Unity 3D中可以通过使用半透明遮罩来实现模型的半透明效果。半透明遮罩是一种材质技术,用于在3D场景中将某些部分的模型透明化,使其能够透过来展示其他模型或场景。 要实现半透明遮罩,首先需要为模型创建一个透明的材质。可以在Unity中选择一个透明的材质,如Standard(Transparent) 或 Legacy Shaders/Transparent/Diffuse等。然后,将这个材质拖拽到模型的渲染组件上。 接下来,在材质的设置中,可以调整透明度的参数。可以通过改变材质的Alpha通道值来控制透明度。Alpha通道的取值范围为0(完全透明)到1(完全不透明),可以根据需求进行调整。在半透明的情况下,可以设置为0.5,或根据需要的透明程度进行调整。 此外,也可以使用Shader来实现更复杂的半透明效果。Unity提供了一些内置的Shader,如Transparent/Diffuse 或 Transparent/Cutout/Diffuse等。这些Shader可以通过改变其属性和参数来实现不同的半透明效果。 在设计场景时,可以在需要半透明遮罩的模型上应用透明材质或Shader,然后设置其透明度,从而实现半透明效果。通过调整不同模型的透明度和位置,可以创造出复杂的遮罩效果,使场景看起来更加真实和有层次感。 总而言之,Unity 3D中可以通过使用透明材质和Shader来实现模型的半透明遮罩效果。通过调整透明度的参数和属性,可以创建出不同透明度和遮罩效果的模型,使场景更加逼真和生动。 ### 回答3: Unity 3D是一款常用的游戏开发引擎,它支持各种3D模型的创建和操作。在Unity 3D中实现模型的半透明遮罩可以通过设置材质的透明度来实现。 首先,需要为模型创建一个材质,可以在Unity的资源管理器中右键点击,并选择创建-材质来创建一个新的材质。在材质的属性面板中,可以调整材质的颜色、透明度和纹理等属性。 要实现半透明效果,需要将材质的透明度设置为0到1之间的值,0表示完全透明,1表示完全不透明。在透明度的下拉菜单中,可以选择合适的透明度类型,例如Alpha Blend(标准透明度混合)或Alpha Test(透明度测试)等。 另外,还可以为材质添加一个透明的贴图。在材质的属性面板中,可以选择一个透明贴图,并通过调整贴图的透明度来改变模型的透明度。 除了设置材质的透明度之外,还可以通过物体的渲染模式来控制透明度。在模型的Inspector面板中,打开“Renderer”选项卡,并在“Material”一栏中选择创建好的材质。然后,在渲染模式的下拉菜单中选择合适的选项,例如Opaque(不透明)、Transparent(半透明)或Fade(渐入渐出)等。 通过以上的设置,就可以在Unity 3D中实现模型的半透明遮罩效果了。可以根据实际需求,调整模型的透明度和颜色,来达到想要的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值