Unity 指引遮罩
2016-03-18 14:45
459 查看
指引遮罩层的作用,主要是屏蔽事件,指定区域穿透事件。在视觉上,遮挡是非遮挡区域有不同的颜色表示。我们分别从事件功能,和视觉功能上来分别介绍。事件功能需要脚本,视觉功能需要shader辅助。本文主要介绍事件功能的实现,shader的视觉辅助下篇介绍。
事件功能上,我们建立四个遮挡层,每个层都会阻挡事件。让后利用4块遮挡层,去围成一个矩形区域形成可点击区域。我们生成一个prefab,里面包含4个屏蔽层。动态的去计算4个屏蔽层的位置。
这里代码片段,是根据可点击区域的中心点和大小,动态计算4个屏蔽区域位置和大小的功能。这里做了适配屏幕的缩放计算。那么,可点击区域,如何让事件接受处理,又能够穿透下去,让本来的事件可以触发执行呢。
我们需要建立另外一个层,覆盖在可点击区域上。实现ICanvasRaycastFilter接口,return false 将会被系统认为碰撞检测失败,事件会被继续传递,同时我们可以再接口中实现我们自己需要的回调。
脚本需要和Image挂载在一起,通过Image的区域来触发碰撞检测。Action的回调中,我们可以把屏蔽层关闭。这个区域需要和上面屏蔽层围成的区域重叠起来。
eventArea 是可点击事件层,EventIgnore 挂载层上,完成事件的穿透和响应双重工作。上面代码仅体现思路,是完成功能代码中截取的,并非直接可以运行。
事件功能上,我们建立四个遮挡层,每个层都会阻挡事件。让后利用4块遮挡层,去围成一个矩形区域形成可点击区域。我们生成一个prefab,里面包含4个屏蔽层。动态的去计算4个屏蔽层的位置。
public RectTransform top; public RectTransform bottom; public RectTransform left; public RectTransform right; private void SetRectCenterInner(Vector2 center, Vector2 size) { RectTransform root = uiRoot.GetComponent<RectTransform>(); Vector2 half = root.sizeDelta * root.localScale.x / 2; Vector2 halfSize = size * root.localScale.x / 2; top.sizeDelta = root.sizeDelta; bottom.sizeDelta = root.sizeDelta; left.sizeDelta = root.sizeDelta; right.sizeDelta = root.sizeDelta; Vector2 tl = new Vector2(center.x - halfSize.x, center.y + halfSize.y); Vector2 br = new Vector2(center.x + halfSize.x, center.y - halfSize.y); top.position = new Vector3(0, tl.y + half.y, 0); bottom.position = new Vector3(0, br.y - half.y, 0); left.position = new Vector3(tl.x - half.x, br.y + halfSize.y, 0); right.position = new Vector3(br.x + half.x, br.y + halfSize.y, 0); left.sizeDelta = new Vector2(left.sizeDelta.x, size.y); right.sizeDelta = new Vector2(right.sizeDelta.x, size.y); }
这里代码片段,是根据可点击区域的中心点和大小,动态计算4个屏蔽区域位置和大小的功能。这里做了适配屏幕的缩放计算。那么,可点击区域,如何让事件接受处理,又能够穿透下去,让本来的事件可以触发执行呢。
我们需要建立另外一个层,覆盖在可点击区域上。实现ICanvasRaycastFilter接口,return false 将会被系统认为碰撞检测失败,事件会被继续传递,同时我们可以再接口中实现我们自己需要的回调。
public class EventIgnore : MonoBehaviour, ICanvasRaycastFilter { public Action action; public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera) { #if UNITY_EDITOR || UNITY_STANDALONE_WIN if (Input.GetMouseButtonDown(0)) { action(); } #else if (Input.touchCount == 1) { Touch touch = Input.GetTouch(0); if (touch.phase == TouchPhase.Began) { action(); } } #endif return false; }
脚本需要和Image挂载在一起,通过Image的区域来触发碰撞检测。Action的回调中,我们可以把屏蔽层关闭。这个区域需要和上面屏蔽层围成的区域重叠起来。
public class GuideMask : MonoBehaviour { public RectTransform top; public RectTransform bottom; public RectTransform left; public RectTransform right; public RectTransform eventArea; private void SetRectCenterInner(Vector2 center, Vector2 size) { RectTransform root = uiRoot.GetComponent<RectTransform>(); Vector2 half = root.sizeDelta * root.localScale.x / 2; Vector2 halfSize = size * root.localScale.x / 2; top.sizeDelta = root.sizeDelta; bottom.sizeDelta = root.sizeDelta; left.sizeDelta = root.sizeDelta; right.sizeDelta = root.sizeDelta; Vector2 tl = new Vector2(center.x - halfSize.x, center.y + halfSize.y); Vector2 br = new Vector2(center.x + halfSize.x, center.y - halfSize.y); top.position = new Vector3(0, tl.y + half.y, 0); bottom.position = new Vector3(0, br.y - half.y, 0); left.position = new Vector3(tl.x - half.x, br.y + halfSize.y, 0); right.position = new Vector3(br.x + half.x, br.y + halfSize.y, 0); left.sizeDelta = new Vector2(left.sizeDelta.x, size.y); right.sizeDelta = new Vector2(right.sizeDelta.x, size.y); eventArea.position = new Vector3(center.x, center.y, 0); eventArea.sizeDelta = size; } }
eventArea 是可点击事件层,EventIgnore 挂载层上,完成事件的穿透和响应双重工作。上面代码仅体现思路,是完成功能代码中截取的,并非直接可以运行。
相关文章推荐
- Unity-碰撞
- unity ulua之lua调用c#
- unity 单列
- [插件资源] Inventory Pro 2.3.1 - Unity 5专用的背包系统
- Unity使用系统字体
- Unity编辑器模式下退出
- Unity-资源
- Unity-视图
- Unity-视图操作
- Unity脚本——Csharp
- Unity ugui slider制作loading条 拉升变形的解决
- unity ngui学习(三)
- Unity5.3.2 记录
- Unity Shaders and Effects Cookbook (1-3) 创建 Half Lambert 光照模型
- iTween基础之Fade(淡入淡出)
- Unity ios、android、pc一键打包(一)
- Unity3D 语音接入适用于pc、ios、android
- Unity3D中基本GUI控件介绍
- Unity中自带时间函数的执行顺序(全部完整版)
- 3DMax extort FBX and import to unity