服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - Unity实现新手引导镂空效果

Unity实现新手引导镂空效果

2022-08-27 15:41LLLLL__ C#

这篇文章主要为大家详细介绍了Unity实现新手引导的镂空效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Unity实现新手引导镂空效果的具体代码,供大家参考,具体内容如下

Unity实现新手引导镂空效果

一、实现思路

创建有8个顶点的Mesh,内外边界都是四边形(矩形)。只生成内、外边之间的Mesh,内层矩形就产生了镂空部分,外层的4个顶点,是组件自身RectTransform的四个顶点,内层的4个顶点,使用镂空目标(_target)RectTransform的四个顶点。确定内层的顶点的时候需要注意,多数情况下_target和HollowOutMask都不在同一个本地坐标空间,所以需要使用CalculateRelativeRectTransformBounds计算出HollowOutMask空间下坐标
这种镂空的表现,可以稍稍提高下性能。因为镂空的位置不参与渲染,Overdraw会降低

UGUI提供了ICanvasRaycastFilter接口,我们实现IsRaycastLocationValid方法,就可以很方便的控制HollowOutMask是否要拦截下在某一点触发的事件

二、这个组件的作用

这个组件做了两件事情:表现上镂空一块区域和不拦截镂空范围上的事件

三、代码实现

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
using UnityEngine;
using UnityEngine.UI;
 
/// <summary>
/// 实现镂空效果的Mask组件
/// </summary>
public class HollowOutMask : MaskableGraphic, ICanvasRaycastFilter
{
 [SerializeField]
 private RectTransform _target;
 
 private Vector3 _targetMin = Vector3.zero;
 private Vector3 _targetMax = Vector3.zero;
 
 private bool _canRefresh = true;
 private Transform _cacheTrans = null;
 
 /// <summary>
 /// 设置镂空的目标
 /// </summary>
 public void SetTarget(RectTransform target)
 {
 _canRefresh = true;
 _target = target;
 _RefreshView();
 }
 
 private void _SetTarget(Vector3 tarMin, Vector3 tarMax)
 {
 if (tarMin == _targetMin && tarMax == _targetMax)
 return;
 _targetMin = tarMin;
 _targetMax = tarMax;
 SetAllDirty();
 }
 
 private void _RefreshView()
 {
 if (!_canRefresh) return;
 _canRefresh = false;
 
 if (null == _target)
 {
 _SetTarget(Vector3.zero, Vector3.zero);
 SetAllDirty();
 }
 else
 {
 Bounds bounds = RectTransformUtility.CalculateRelativeRectTransformBounds(_cacheTrans, _target);
 _SetTarget(bounds.min, bounds.max);
 }
 }
 
 protected override void OnPopulateMesh(VertexHelper vh)
 {
 if (_targetMin == Vector3.zero && _targetMax == Vector3.zero)
 {
 base.OnPopulateMesh(vh);
 return;
 }
 
 vh.Clear();
 
 // 填充顶点
 UIVertex vert = UIVertex.simpleVert;
 vert.color = color;
 
 Vector2 selfPiovt = rectTransform.pivot;
 Rect selfRect = rectTransform.rect;
 float outerLx = -selfPiovt.x * selfRect.width;
 float outerBy = -selfPiovt.y * selfRect.height;
 float outerRx = (1 - selfPiovt.x) * selfRect.width;
 float outerTy = (1 - selfPiovt.y) * selfRect.height;
 // 0 - Outer:LT
 vert.position = new Vector3(outerLx, outerTy);
 vh.AddVert(vert);
 // 1 - Outer:RT
 vert.position = new Vector3(outerRx, outerTy);
 vh.AddVert(vert);
 // 2 - Outer:RB
 vert.position = new Vector3(outerRx, outerBy);
 vh.AddVert(vert);
 // 3 - Outer:LB
 vert.position = new Vector3(outerLx, outerBy);
 vh.AddVert(vert);
 
 // 4 - Inner:LT
 vert.position = new Vector3(_targetMin.x, _targetMax.y);
 vh.AddVert(vert);
 // 5 - Inner:RT
 vert.position = new Vector3(_targetMax.x, _targetMax.y);
 vh.AddVert(vert);
 // 6 - Inner:RB
 vert.position = new Vector3(_targetMax.x, _targetMin.y);
 vh.AddVert(vert);
 // 7 - Inner:LB
 vert.position = new Vector3(_targetMin.x, _targetMin.y);
 vh.AddVert(vert);
 
 // 设定三角形
 vh.AddTriangle(4, 0, 1);
 vh.AddTriangle(4, 1, 5);
 vh.AddTriangle(5, 1, 2);
 vh.AddTriangle(5, 2, 6);
 vh.AddTriangle(6, 2, 3);
 vh.AddTriangle(6, 3, 7);
 vh.AddTriangle(7, 3, 0);
 vh.AddTriangle(7, 0, 4);
 }
 
 bool ICanvasRaycastFilter.IsRaycastLocationValid(Vector2 screenPos, Camera eventCamera)
 {
 if (null == _target) return true;
 // 将目标对象范围内的事件镂空(使其穿过)
 return !RectTransformUtility.RectangleContainsScreenPoint(_target, screenPos, eventCamera);
 }
 
 protected override void Awake()
 {
 base.Awake();
 _cacheTrans = GetComponent<RectTransform>();
 }
 
#if UNITY_EDITOR
 void Update()
 {
 _canRefresh = true;
 _RefreshView();
 }
#endif
}

四、使用说明

将以上组件挂载到有RectTransform组件的游戏物体身上,设置Color的颜色以及Target区域的大小即可

——此组件挂载的游戏物体身上只能有一个继承Graphics类的组件
——若自定义添加Image控制Target区域大小,记得将Image的Alpha设置为0并且取消射线检测

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/LLLLL__/article/details/104263122

延伸 · 阅读

精彩推荐
  • C#Silverlight将图片转换为byte的实现代码

    Silverlight将图片转换为byte的实现代码

    这篇文章主要介绍了Silverlight将图片转换为byte的实现代码,需要的朋友可以参考下...

    C#教程网10252021-11-02
  • C#C# 实现截图软件功能实例代码

    C# 实现截图软件功能实例代码

    这篇文章主要介绍了C# 实现截图软件功能实例代码,需要的朋友可以参考下...

    C#教程网9852022-01-07
  • C#微信开发--企业转账到用户

    微信开发--企业转账到用户

    本文主要介绍了微信开发--企业转账到用户的实现方法与步骤。具有很好的参考价值,下面跟着小编一起来看下吧...

    stoneniqiu9302021-12-20
  • C#Unity3D动态生成平面网格

    Unity3D动态生成平面网格

    这篇文章主要为大家详细介绍了Unity3D动态生成平面网格,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    星空不语10742022-03-10
  • C#C#使用AutoResetEvent实现同步

    C#使用AutoResetEvent实现同步

    这篇文章主要为大家详细介绍了C#使用AutoResetEvent实现同步的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    章为忠6132021-12-30
  • C#C#实现可捕获几乎所有键盘鼠标事件的钩子类完整实例

    C#实现可捕获几乎所有键盘鼠标事件的钩子类完整实例

    这篇文章主要介绍了C#实现可捕获几乎所有键盘鼠标事件的钩子类,以完整实例形式分析了C#捕获键盘鼠标事件的钩子操作技巧,具有一定参考借鉴价值,需要的...

    smartsmile201210312021-11-24
  • C#C#实现的简单链表类实例

    C#实现的简单链表类实例

    这篇文章主要介绍了C#实现的简单链表类,涉及C#针对链表的定义、实现及链表节点的增加、删除与修改技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    北风其凉6882021-10-19
  • C#基于C#实现网页爬虫

    基于C#实现网页爬虫

    这篇文章主要为大家详细介绍了基于C#实现网页爬虫的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    秋荷雨翔11002021-11-16