Unity射线检测的判定Bug

文章讲述了在Unity中使用射线检测进行物体穿透问题的解决过程,包括最初使用SweepTest遇到的问题,以及通过反转射线和排序RaycastHit来找到目标点的方法。然而,作者发现近的物体检测位置异常,可能是Unity内部排序问题。
摘要由CSDN通过智能技术生成

射线简介

射线检测在unity中使用的非常广泛,不管是2D还是3D都有很多的用途,像是判定鼠标点击的位置还有动作游戏的攻击范围的判定。

最近在实现一个传送的功能:传送一个固定的距离,如果中间有物体阻挡就传到碰撞的物体上。

整体功能难度不高

//这个方法本身就是发射一条射线,写起来快所以最早就先这么干了
if (selfRigidbody.SweepTest(dir, out hit, length))
{
	//通过命中点和自身的坐标处理使本体不会穿墙	
    var hitpoint = hit.point;
    //这里获取自身距离碰撞点最近的坐标
    var selClosesthitPoint = selfRigidbody.ClosestPointOnBounds(hitpoint);
	//这里得到该点和自身坐标的差,获取自身的厚度
    var closestPoint = selClosesthitPoint - trans.position;
	//击中点和厚度相减保证不会卡墙
    selfRigidbody.MovePosition(hitpoint - closestPoint);
}
else
{            
    //为击中时的情况
    trans.position = telPoint;
}*/

​ 但在实际运行中总是会出现一个问题,总是会穿过贴着的物体传到碰撞体里面去,一开始觉得会不会是因为靠太近了导致物体外侧网格碰撞面被自身挡住了,因为射线在没更改设置的情况下只能检测到物体的网格碰撞体的外层,内部是检测不到的,必须开启这个设置才行,

在这里插入图片描述

这也是为什么设置源点射线位置在自身时不会检测到自己。所以去搜了一下怎么在内侧检测到碰撞体,然后大不了把自身给去掉就行了。

​ 找确实找到了https://github.com/yangruihan/blog/issues/29,反转射线就可以了,拿这个再检测一次就行了。

/// <summary>
/// 反转射线
/// </summary>
public static Ray Reverse(this Ray ray, float distance)
{
    return new Ray(
        ray.origin + ray.direction * distance,
        -ray.direction);
}

​ 不过仔细想了一下这个功能需求和我要的不一样,这个只能是检测该方向上有物体(实际试了一下确实也没有用)。

​ 之后想不出来,就改了代码调试一下看看到底使用射线时获取到了啥玩意

RaycastHit[] hits;
Ray ray = new Ray(position, dir);
//RaycastNonAlloc的参数数组是提前分配的大小
//RaycastAll是动态获取分配的数组,内存资源比上面的消耗大
//hits = Physics.RaycastAll(ray,length);
//Debug.DrawLine(position,endPoint,Color.red,5f);
hits = Physics.RaycastAll(ray,length);
if(hits.Length > 0)
{
    
    var targetPoint = hits[0].point;
    var selfClosedPoint = selfRigidbody.ClosestPointOnBounds(targetPoint);
    //获取自身厚度的坐标差
    var closetPoint = selfClosedPoint - _mTrans.position;
    //这个是最后移动的坐标长
    selfRigidbody.MovePosition(targetPoint - closetPoint);
}
else
{
    _mTrans.position = telPoint;
}

还是没用,试着获取数量看看

在这里插入图片描述

6,获取了两个物体,好了破案了,写个比较函数丢给Array.List排序委托就行了

public int Compare(RaycastHit hit1, RaycastHit hit2)
    {
        var pos = _mTrans.position;
        var dis1 = Vector3.Distance(hit1.point, pos);
        var dis2 = Vector3.Distance(hit2.point, pos);
        if (dis1 > dis2)
        {
            return 1;
        }
        else
            return -1;

        return 0;
    }

不知道为什么近的物体反而会排在第二位了,之前直接拿SweepTest测试没得到的原因也知道了,第一个获取的是地板的点,当然不会测到Cube的碰撞体了。

+++

bug是解决了,就是不知道为什么近的点会排到后面去,应该是unity的问题

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值