unity不规则点击_【Unity游戏开发】UGUI不规则区域点击的实现

本文介绍了在Unity中处理UGUI不规则区域点击的两种方法:1. 精灵像素检测,通过调整alphaHitTestMinimumThreshold属性实现;2. 通过算法计算碰撞区域,利用Polygon Collider组件结合算法判断点是否在多边形内。通过实例展示了这两种方法的实现细节和注意事项,包括图片设置、坐标转换以及可能遇到的偏移问题。
摘要由CSDN通过智能技术生成

一、简介

马三从上一家公司离职了,最近一直在出去面试,忙得很,所以这一篇博客拖到现在才写出来。马三在上家公司工作的时候,曾处理了一个UGUI不规则区域点击的问题,制作过程中也有一些收获和需要注意坑,因此记录成博客与大家分享。众所周知在UGUI中,响应点击通常是依附在一张图片上的,而图片不管美术怎么给你切,导进Unity之后都是一个矩形,如果要做其他形状,最多只能旋转一下,或者自己做一些处理。而为了美术效果,很多时候我们不得不需要特定形状的UI,并且让它们实现精准的响应点击。例如下图就是一个不规则的点击区域。

图1:UGUI不规则点击区域示意图

下面是处理了不规则区域点击后的演示效果,当点击按钮的时候,会对点击次数进行累加并且打印到控制台。可以看到进行了不规则区域点击处理以后,对我们原来的普通矩形Sprite的点击不会产生到影响,而不规则区域的表现效果也符合我们的预期。

图2:规则区域与不规则区域点击效果对比

二、针对UGUI不规则区域点击的两种处理方法

针对UGUI的不规则区域响应点击,一般来说有两种处理办法:

1.精灵像素检测:该方法是指通过读取精灵(Sprite)在某一点的像素值(RGBA),如果该点的像素值中的Alpha小于一定的阈值(比如0.5)则表示该点处是透明的,即用户点击的位置在精灵边界以外,否则用户点击的位置在精灵边界内部。

2.通过算法计算碰撞区域:通过一定的算法,手动计算出碰撞区域,然后在判断用户是点击在了精灵上面,还是点击在精灵外部。

1.精灵像素检测法

首先来说下精灵像素检测法,因为它实现起来比较简单也好理解。uGUI在处理控件是否被点击的时候,主要是根据IsRaycastLocationValid这个方法的返回值来进行判断的,而这个方法用到的基本原理则是判断指定点对应像素的RGBA数值中的Alpha是否大于某个指定临界值。例如,我们知道半透明通常是指Alpha=0.5,而对一个后缀名为png格式的图片来说半透明或者完全透明的区域理论上不应该被响应的,所以根据这个原理,我们只需要设定一个透明度的临界值,然后对当前鼠标位置对应的像素进行判断就可以了,因此这种方法叫做精灵像素检测。对于上面的这个IsRaycastLocationValid接口,我们可以通过下载UGUI源码或者反编译的方式看到它的实现:

1 public virtual boolIsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera)2 {3 //当透明度>=1.0时,表示点击在可响应区域返回true

4 if(this.m_EventAlphaThreshold >=1f){5 return true;6 }7

8 //当没有指定精灵时返回true,因为不指定Spirte的时候,Unity将其区域填充为默认的白色,全部区域都是可以响应点击的

9 Sprite overrideSprite = this.overrideSprite;10 if(overrideSprite == null){11 return true;12 }13

14 //坐标系转换

15 Vector2 local;16 RectTransformUtility.ScreenPointToLocalPointInRectangle(base.rectTransform, screenPoint, eventCamera, reflocal);17 Rect pixelAdjustedRect = base.GetPixelAdjustedRect ();18 local.x += base.rectTransform.get_pivot ().x *pixelAdjustedRect.get_width ();19 local.y += base.rectTransform.get_pivot ().y *pixelAdjustedRect.get_height ();20 local = this.MapCoordinate(local, pixelAdjustedRect);21 Rect textureRect =overrideSprite.get_textureRect ();22 Vector2 vector = new Vector2(local.x / textureRect.get_width (), local.y /textureRect.get_height ());23

24 //计算屏幕坐标对应的UV坐标

25 float num = Mathf.Lerp(textureRect.get_x (), textureRect.get_xMax (), vector.x) / (float)overrideSprite.get_texture().get_width();26 float num2 = Mathf.Lerp(textureRect.get_y (), textureRect.get_yMax (), vector.y) / (float)overrideSprite.get_texture().get_height();27 boolresult;28

29 //核心方法:像素检测

30 try{31 result = (overrideSprite.get_texture().GetPixelBilinear(num, num2).a >&#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值