接上一篇文章 UGUI研究院之忽略UI被拦截事件(十三)
比如一些不规则按钮最好可以设置它的响应区域。如下图所示,用Polygon Collider2D组件圈出精灵响应事件的区域。
注意 IsRaycastLocationValid 的判断区域是RectTransform的区域。 如果 polygon Collider编辑出来的区域大于RectTransform , 必须调节RectTransform的区域。
例子:比如想把按钮的点击区域改成不规则的。
1.把按钮的image的RaycastTarget关闭勾选
2.在子节点创建新的gameObject挂上下面UIPolygon脚本。
3.编辑Polygon的区域即可。
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif
[RequireComponent(typeof(PolygonCollider2D))]
public class UIPolygon : Image
{
private PolygonCollider2D _polygon = null;
private PolygonCollider2D polygon
{
get{
if(_polygon == null )
_polygon = GetComponent<PolygonCollider2D>();
return _polygon;
}
}
protected UIPolygon()
{
useLegacyMeshGeneration = true;
}
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
}
public override bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera)
{
return polygon.OverlapPoint( eventCamera.ScreenToWorldPoint(screenPoint));
}
#if UNITY_EDITOR
protected override void Reset()
{
base.Reset();
transform.localPosition = Vector3.zero;
float w = (rectTransform.sizeDelta.x *0.5f) + 0.1f;
float h = (rectTransform.sizeDelta.y*0.5f) + 0.1f;
polygon.points = new Vector2[]
{
new Vector2(-w,-h),
new Vector2(w,-h),
new Vector2(w,h),
new Vector2(-w,h)
};
}
#endif
}
#if UNITY_EDITOR
[CustomEditor(typeof(UIPolygon), true)]
public class UIPolygonInspector : Editor
{
public override void OnInspectorGUI()
{
}
}
#endif
- 本文固定链接: https://www.xuanyusong.com/archives/3492
- 转载请注明: 雨松MOMO于 雨松MOMO程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!


在PC上,如果使用Overlay模式,会报错,要自己手动设置eventCamera吗?
这个用不起来呀,IsRaycastLocationValid报错 NullReferenceException: Object reference not set to an instance of an object
UIPolygon.IsRaycastLocationValid (Vector2 screenPoint, UnityEngine.Camera eventCamera) (at Assets/UIPolygon.cs:29)
不应该啊, 我们也是这样用的。。
是的会报错,就是return polygon.OverlapPoint( eventCamera.ScreenToWorldPoint(screenPoint));这段代码报错
给根部的Canvas挂上一个摄像机,或者直接在这方法里赋予当前的全局相机即可
我的也是这个问题 ,不知道你的解决没有
手机上就不会了。 因为电脑上要判断悬浮状态。。
雨松大神,我使用你这种方法在960*640的画布上可以,但是到1920*1080的画布就不行了。而且在960*640的画布上如果我缩小或者放大窗口,也会出现问题。我想请问一下应该怎么修改呢?万分期待你的回复~~~~
能否针对一个toggle写个例子,框入的响应,不框入的不响应,怎么利用这个脚本去做到
当你把rendermode换成Camera都不行了,请问有什么好的办法吗
怎么判断我点击那块区域了,还是要用button么
监听
我试了好久。添加了一个Polygon Collider2D到Button上,Collider的区域特别小,应该只是0.01倍。最重要的是点击Edit Collider无法编辑。后来找到了http://blog.csdn.net/fg5823820/article/details/48165659这个文章,发现我的Canvas的Z轴不是0,但是此处无法直接修改它。于是修改Canvas组件的Plane Distance直到Z变成0,这个时候奇迹发生了,Polygon Collider可以编辑了,虽然不明所以,不过我觉得可以分享给大家~
这个方法好像不支持屏幕缩放吧!
居然不可以超过图片区域,这点相当不灵活啊
你可以建一个空UI对象(想多大就多大,反正包住Collider就行),将图片作为他的子对象,Collider针对这个空UI对象,这样图片区域的限定就没有了。
你可以建一个空UI对象(想多大就多大,反正长宽能包住Collider就行),将图片作为他的子对象,Collider针对这个空UI对象操作,这样图片区域的限定就没有了。
大概是判断点击在图像上的位置,来判断是否可以触发点击事件!
大大,如何设置图片啊。初学者求指导
謝謝你 雨松大大
好东西!
请问判断点是否在区域内能否直接使用Collider2D.OverlapPoint?
可以。
那这样自己算的效率会更高吗?
有限制, 因为这东西必须要挂collider2d组件,但是UI都是没有这个组件地。。
可以使用Image的eventAlphaThreshold啦~~~设置前需要改一下Sprite的TextureType用Advanced,然后设置Read/Write Enabled,还要不使用Sprite Atlas…限制挺多..
为什么要开 Read/Write Enabled ? 开了以后内存就Double了啊。。 不用Sprite Atlas draw call 不就上去了么?
您好,eventAlphaThreshold具体怎么用,文档上没有详细粒子,看不清楚,可否教下?
大神我想问下,为什么我设置了区域,点击其他地方还是会响应点击事件
UGUI不是用Collider触发点击事件的,是用射线
大神,我想问下,如何扩大图片的响应区域呀?我发现当Collider2D组件范围超出图片之后。超出的那部分不会响应事件,IsRaycastLocationValid函数也没有触发。
UI里面 没有用 组件的collider做射线碰撞。。 所以 你加了collider 它的射线就检测不到了。 这种需求就自己做射线吧。。。
如何让超出的部分响应事件啊
期待更新
谢谢啦。。
好办法,用来改成3D物品响应也应该可以哦
3D可能不行, 因为3D要用 3D摄像机了。。