Unity之引导功能遮罩事件穿透
Posted 彩色墨水
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity之引导功能遮罩事件穿透相关的知识,希望对你有一定的参考价值。
Unity之新手引导shader遮罩事件穿透
效果图
设计思路
1.新手引导我们期待开发内容不影响正常的功能模块,意思就是分层,新手引导在正常功能之上
2.新手引导层级用一层深色bg显示遮住正常功能层级,在需要引导的位置留出高亮区域
3.在这个新手引导层做事件渗透,给指定的对象或UI做事件渗透,如果点击交互位置处于指定UI或对象范围内,让事件渗透新手引导层,到正常功能层。
场景搭建
搭建两个层级
一个正常功能层级为Canvas下,一个新手引导层级在GuideHolder下。
制作新手引导的预制体
材质使用我们特制的带镂空效果的材质shader,并挂载一个事件渗透作用的脚本
代码
这里有两个比较重要的内容,一个是遮罩层是深色的,并要镂空指定区域做高亮,这里使用shader去制作效果图。二是在合适时机做指定区域的事件渗透。
GuideMask.cs
/// <summary>
/// 创建圆形点击区域
/// </summary>
/// <param name="pos">圆心的屏幕位置</param>
/// <param name="rad">圆的半径</param>
/// <param name="CallBack">点击的回调</param>
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 Off
Lighting Off
ZWrite Off
ZTest[unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask[_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_RECT
color.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
以上是关于Unity之引导功能遮罩事件穿透的主要内容,如果未能解决你的问题,请参考以下文章