热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Unity之引导功能遮罩事件穿透

Unity之新手引导shader遮罩事件穿透效果图设计思路1.新手引导我们期待开发内容不影响正常的功能模块,意思就是分层,新手引导在正常功能之上2.

Unity之新手引导shader遮罩事件穿透


效果图

新手指引演示


设计思路

1.新手引导我们期待开发内容不影响正常的功能模块,意思就是分层,新手引导在正常功能之上
2.新手引导层级用一层深色bg显示遮住正常功能层级,在需要引导的位置留出高亮区域
3.在这个新手引导层做事件渗透,给指定的对象或UI做事件渗透,如果点击交互位置处于指定UI或对象范围内,让事件渗透新手引导层,到正常功能层。


场景搭建


搭建两个层级

新手引导Hierarchy面板

新手引导Hierarchy面板
一个正常功能层级为Canvas下,一个新手引导层级在GuideHolder下。


制作新手引导的预制体

在这里插入图片描述
材质使用我们特制的带镂空效果的材质shader,并挂载一个事件渗透作用的脚本


代码

这里有两个比较重要的内容,一个是遮罩层是深色的,并要镂空指定区域做高亮,这里使用shader去制作效果图。二是在合适时机做指定区域的事件渗透。

GuideMask.cs

///

/// 创建圆形点击区域/// ///

圆心的屏幕位置///

圆的半径///

点击的回调public void CreateCircleMask(Vector3 pos, float rad, GameObject target){ShowGuideMask(()=> {ShowTween = true;ev.SetTargetImage(target);_rectTrans.sizeDelta = Vector2.zero;_materia.SetFloat("_MaskType", 0f);CurRadNum = rad;_materia.SetVector("_Origin", new Vector4(pos.x, pos.y, rad + 1000, 20));});}public void ShowGuideMask(Action callback){ShowTween = false;if (_rectTrans == null){ResMgr.Instance.Load("GuideSystem", (obj) => {guide = Instantiate((GameObject)obj, ISceneManager.Instance.GuideHolder);_rectTrans = guide.GetComponent<RectTransform>();_rawImage = guide.GetComponent<RawImage>();_rawImage.color = new Color(1, 1, 1, 1);_materia = _rawImage.material;ev = guide.GetComponent<EventPenetrate>();callback();});}else{callback();}}

GuideMask.shader

Shader "UI/GuideMask"
{Properties{[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}_Color("Tint", Color) = (1,1,1,1)_Blur("边缘虚化的范围", Range(1,1000)) = 100_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//中心_Origin("Circle",Vector) = (0,0,0,0)//裁剪方式 0圆形 1圆形_MaskType("Type",Float) = 0 }SubShader{Tags{"Queue" = "Transparent""IgnoreProjector" = "True""RenderType" = "Transparent""PreviewType" = "Plane""CanUseSpriteAtlas" = "True"}Stencil{Ref[_Stencil]Comp[_StencilComp]Pass[_StencilOp]ReadMask[_StencilReadMask]WriteMask[_StencilWriteMask]}Cull OffLighting OffZWrite OffZTest[unity_GUIZTestMode]Blend SrcAlpha OneMinusSrcAlphaColorMask[_ColorMask]Pass{Name "Default"CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0#include "UnityCG.cginc"
#include "UnityUI.cginc"struct appdata_t{float4 vertex : POSITION;float4 color : COLOR;float2 texcoord : TEXCOORD0;UNITY_VERTEX_INPUT_INSTANCE_ID};struct v2f{float4 vertex : SV_POSITION;fixed4 color : COLOR;float2 texcoord : TEXCOORD0;float4 worldPosition : TEXCOORD1;UNITY_VERTEX_OUTPUT_STEREO};fixed4 _Color;fixed4 _TextureSampleAdd;float4 _ClipRect;float4 _Origin;float _MaskType; float _Blur;v2f vert(appdata_t IN){v2f OUT;UNITY_SETUP_INSTANCE_ID(IN);UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);OUT.worldPosition = IN.vertex;OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);OUT.texcoord = IN.texcoord;OUT.color = IN.color * _Color;return OUT;}sampler2D _MainTex;fixed4 frag(v2f IN) : SV_Target{half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;if (_MaskType == 0) {//if (distance(IN.worldPosition.xy, _Origin.xy) <= _Origin.z)//{// color.a = 0;//} float dis = distance(IN.worldPosition.xy, _Origin.xy);//过滤掉距离小于(半径-过渡范围)的片元clip(dis - (_Origin.z - _Blur));//优化if条件判断,如果距离小于半径则执行下一步,等于if(dis <_Radius)fixed tmp = step(dis, _Origin.z);//计算过渡范围内的alpha值color.a *= (1 - tmp) + tmp * (dis - (_Origin.z - _Blur)) / _Blur;}else if (_MaskType == 1) {//UnityGet2DClipping这个函数实现了判断2D空间中的一点是否在一个矩形区域中if (UnityGet2DClipping(IN.worldPosition.xy, _Origin)){color.a = 0;}}else if (_MaskType == 2){if (UnityGet2DClipping(IN.worldPosition.xy, _Origin)){color.a = 0;#ifdef UNITY_UI_CLIP_RECTcolor.a *= UnityGet2DClipping(IN.worldPosition.xy, _Origin);#endif} }return color;}ENDCG}}
}

调用

GuideMask.Instance.CreateCircleMaskoffset(button2.gameObject, 0, null);GuideMask.Instance.CloseGuideMask();

工程项目

链接:https://pan.baidu.com/s/1v4laE9QdqRGWKqfKJpnkxQ
提取码:s8qc


推荐阅读
author-avatar
Angels萱萱
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有