UGUI实现不规则形状图片触发

本文介绍在Unity中实现多边形点击检测的两种方法。一种是通过计算叉乘判断点击位置是否在多边形内,另一种是利用Collider组件的API进行检测。提供了具体的代码实现,适用于游戏开发和交互设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果如下

有两种比较主流的实现方式,一种是根据图片像素的alpha值来判断是否触发响应,还有一种是自己框选一个多边体,判断点击位置是否在多变体内。
第一种像素使用限制颇多,但是也有一定的使用场景,https://www.cnblogs.com/msxh/p/9283266.html,这里马三详细说了使用方法和限制
我在这里实现的是第二种计算的方式

P点是鼠标位置,ABCD是多边形的点,如果图上对每个点计算叉乘的方向都是一致,那我们可以得出P点在多边形内部,有一定的叉乘知识应该可以推出来。叉乘可以看看这篇文章 https://blog.youkuaiyun.com/qq_33413868/article/details/87929981

下面上代码实现:

public class MImage : Image
{
    //多边形使用PolygonCollider2D来代替,但是推荐自己写一个,我们只需要使用collider2D.points来按顺序获取所有
    //的点,PolygonCollider2D似乎有些大材小用,这里只做演示
    private PolygonCollider2D collider2D;
    private bool? dir;
    protected override void Awake()
    {
        base.Awake();
        collider2D = GetComponent<PolygonCollider2D>();
    }

    /// <summary>
    /// unity判断是否选中的方法,可以继承Image来重写
    /// </summary>
    /// <param name="screenPoint"></param>
    /// <param name="eventCamera"></param>
    /// <returns></returns>
    public override bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera)
    {
        dir = null;
        screenPoint = screenPoint - (Vector2)rectTransform.position;
        int len = collider2D.points.Length;
        for (int i = 0; i < len; i++)
        {
            //求每条边的方向向量
            var side_dir = collider2D.points[(i + 1) % len] - collider2D.points[i];
            //求当前点和边的向量叉乘 的朝向
            bool _dir = Vector3.Cross(screenPoint - collider2D.points[i], side_dir).z > 0;
            if (!dir.HasValue)
                dir = _dir;
            if (dir.Value != _dir)
                return false;
        }
        return true;
    }
}

还有第二种计算是使用collider自带的api

public bool IsRaycastLocationValid(Vector2 screenPos, Camera eventCamera)
        {
            var worldPoint = Vector3.zero;
            var isInside = RectTransformUtility.ScreenPointToWorldPointInRectangle(
                _rectTransform,
                screenPos,
                eventCamera,
                out worldPoint
            );

            if (isInside)
            {
                isInside = _collider.OverlapPoint(worldPoint);
            }

            return isInside;
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值