Unity UGUI按钮点击的时候,由于有些时候会有透明部分,当点击按钮式总会出现透明部分挡住其他按钮的时候,为了避免这种情况,就有了今天的这个组件。
基本原理就是,获取图片点击位置的像素点颜色,判断是否透明,然后重写IsRaycastLocationValid接口,一开始我用鼠标点击位置,去获取像素点,但是好像没有效果,后来查了资料才知道,图片像素点坐标和鼠标图片上点击的位置,坐标系是不一样的,而且图片的像素坐标还会根据image的大小有变化。文章源自大腿Plus-https://www.zhaoshijun.com/archives/1256
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 |
using UnityEngine; using UnityEngine.UI; public class ImageRaycastFilter : MonoBehaviour, ICanvasRaycastFilter { private Image _image; private Sprite _sprite; [Tooltip("设定Sprite响应的Alpha阈值")] [Range(0, 0.5f)] public float alpahThreshold = 0.5f; void Start() { _image = GetComponent<Image>(); } /// <summary> /// 重写IsRaycastLocationValid接口 /// </summary> /// <param name="sp"></param> /// <param name="eventCamera"></param> /// <returns></returns> public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera) { _sprite = _image.sprite; var rectTransform = (RectTransform)transform; Vector2 localPositionPivotRelative; RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)transform, sp, eventCamera, out localPositionPivotRelative); // 转换为以屏幕左下角为原点的坐标系 var localPosition = new Vector2(localPositionPivotRelative.x + rectTransform.pivot.x * rectTransform.rect.width, localPositionPivotRelative.y + rectTransform.pivot.y * rectTransform.rect.height); var spriteRect = _sprite.textureRect; var maskRect = rectTransform.rect; var x = 0; var y = 0; // 转换为纹理空间坐标 switch (_image.type) { case Image.Type.Sliced: { var border = _sprite.border; // x 轴裁剪 if (localPosition.x < border.x) { x = Mathf.FloorToInt(spriteRect.x + localPosition.x); } else if (localPosition.x > maskRect.width - border.z) { x = Mathf.FloorToInt(spriteRect.x + spriteRect.width - (maskRect.width - localPosition.x)); } else { x = Mathf.FloorToInt(spriteRect.x + border.x + ((localPosition.x - border.x) / (maskRect.width - border.x - border.z)) * (spriteRect.width - border.x - border.z)); } // y 轴裁剪 if (localPosition.y < border.y) { y = Mathf.FloorToInt(spriteRect.y + localPosition.y); } else if (localPosition.y > maskRect.height - border.w) { y = Mathf.FloorToInt(spriteRect.y + spriteRect.height - (maskRect.height - localPosition.y)); } else { y = Mathf.FloorToInt(spriteRect.y + border.y + ((localPosition.y - border.y) / (maskRect.height - border.y - border.w)) * (spriteRect.height - border.y - border.w)); } } break; case Image.Type.Simple: default: { // 转换为统一UV空间 x = Mathf.FloorToInt(spriteRect.x + spriteRect.width * localPosition.x / maskRect.width); y = Mathf.FloorToInt(spriteRect.y + spriteRect.height * localPosition.y / maskRect.height); } break; } // 如果texture导入过程报错,则提示错误原因 try { return _sprite.texture.GetPixel(x, y).a > alpahThreshold; } catch (UnityException e) { Debug.LogError("Mask texture not readable, set your sprite to Texture Type 'Advanced' and check 'Read/Write Enabled'" + e.Message); return false; } } } |
上面就是代码,只要将这个代码放到Button上就可以了,其中那个alpahThreshold是判断是否可以点击的透明度,0是全透明的时候不能点击,0.5是半透明的时候不能点击。文章源自大腿Plus-https://www.zhaoshijun.com/archives/1256
最重要的一点就是图片要设置成可读写文章源自大腿Plus-https://www.zhaoshijun.com/archives/1256
文章源自大腿Plus-https://www.zhaoshijun.com/archives/1256
文章源自大腿Plus-https://www.zhaoshijun.com/archives/1256
我的微信
微信扫一扫

shijun_z
我的QQ
QQ扫一扫

846207670
评论