不规则图片的点击响应

参考链接:http://www.xuanyusong.com/archives/3492

当点击一张不规则图片时,点击镂空区域时,还是会发生响应。



对于Image来说,判断是否点击有效的就是IsRaycastLocationValid函数了,因此要重写它。

另外要为不规则图片挂上PolygonCollider2D组件,圈出响应的范围。


using UnityEngine;  
using System.Collections;  
using UnityEngine.UI;  
  
/// <summary>  
/// Image实现了接口ICanvasRaycastFilter  
/// 该接口有函数IsRaycastLocationValid,返回点击是否有效  
/// </summary>  
public class ImagePlus : Image {  
  
    PolygonCollider2D collider;  
    LineRenderer l;  
  
    void Awake()  
    {  
        collider = GetComponent<PolygonCollider2D>();  
        l = GetComponent<LineRenderer>();  
    }  
  
    override public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)  
    {  
        DrawLine();  
        return ContainsPoint(collider.points,sp);  
    }  
  
    //多边形顶点,屏幕点击坐标  
    bool ContainsPoint (Vector2[] polyPoints, Vector2 p)   
    {   
        int j = polyPoints.Length - 1;   
        bool inside = false;   
  
        for (int i = 0; i < polyPoints.Length; i++)   
        {  
            polyPoints[i].x += transform.position.x;  
            polyPoints[i].y += transform.position.y;  
            if ( ((polyPoints[i].y < p.y && p.y <= polyPoints[j].y) || (polyPoints[j].y < p.y && p.y <= polyPoints[i].y)) &&  
                  (polyPoints[i].x + (p.y - polyPoints[i].y) / (polyPoints[j].y - polyPoints[i].y) * (polyPoints[j].x - polyPoints[i].x)) > p.x)   
                inside = !inside;  
  
            j = i;  
        }   
        return inside;   
    }  
  
    //画出多边形区域  
    void DrawLine()  
    {  
        l.SetVertexCount(collider.points.Length);  
        for (int i = 0; i < collider.points.Length; i++)  
        {  
            float x = collider.points[i].x + transform.position.x;  
            float y = collider.points[i].y + transform.position.y;  
            Vector3 a = new Vector3(x,y,0);  
            l.SetPosition(i,a);  
        }  
    }  
}  

解释:

1.PolygonCollider2D.points得到的点,其坐标是相对于图片中心的,也就是说,无论图片怎么移动,PolygonCollider2D.points中的点的坐标都是不变的,因此,为了得到多边形顶点的屏幕坐标,要加上图片的中心坐标。

2.算法是判断点是否在多边形内,原理可以看这里。其中涉及到射线与线段是否相交,要用到直线方程的点斜式,根据交点个数,从而判断点是否在多边形内。


在测试中,发现响应范围还是有一些误差,在某些离边缘外较近的地方还是会有响应,调整了一些参数还是不能解决,这里先放一放了。


//

后来发现一个更简单的方法:

using UnityEngine;  
using System.Collections;  
using UnityEngine.UI;  
  
public class TestTouch : MonoBehaviour {  
  
    private Image image;  
    private PolygonCollider2D polygonCollider2D;  
      
    // Use this for initialization  
    void Start ()   
    {  
        image = GetComponent<Image>();  
        polygonCollider2D = GetComponent<PolygonCollider2D>();  
    }  
      
    // Update is called once per frame  
    void Update ()   
    {  
        if(Input.GetMouseButtonDown(0))  
            if (polygonCollider2D.OverlapPoint(Input.mousePosition))  
                image.enabled = !image.IsActive();  
    }  
}  



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值