接上一篇文章 UGUI研究院之忽略UI被拦截事件(十三)
比如一些不规则按钮最好可以设置它的响应区域。如下图所示,用Polygon Collider2D组件圈出精灵响应事件的区域。
注意 IsRaycastLocationValid 的判断区域是RectTransform的区域。 如果 polygon Collider编辑出来的区域大于RectTransform , 必须调节RectTransform的区域。
例子:比如想把按钮的点击区域改成不规则的。
1.把按钮的image的RaycastTarget关闭勾选
2.在子节点创建新的gameObject挂上下面UIPolygon脚本。
3.编辑Polygon的区域即可。
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 |
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摄像机了。。