【Unity 2D AABB碰撞检测】铸梦之路

这篇具有很好参考价值的文章主要介绍了【Unity 2D AABB碰撞检测】铸梦之路。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


视屏教程地址:https://www.taikr.com/user/192182

目录

1.AABB 碰撞介绍

AABB 代表的是轴对齐碰撞盒 (Axis-aligned Bounding Box)

AABB碰撞盒是指与场景基础坐标轴(2D中的是x和y轴)对齐的长方形的碰撞外形。与坐标轴对齐意味着这个长方形没有经过旋转并且它的边线和场景中基础坐标轴平行(例如,左右边线和y轴平行)。这些碰撞盒总是和场景的坐标轴平行,这使得所有的计算都变得更简单。

2.常用2D碰撞盒

一般在2D环境下,常用的碰撞盒有一下几种种。

  • 1.BOX(方形) 碰撞
  • 2.Sphere(圆形) 碰撞
  • 3.BOX&Sphere(方形与圆形) 碰撞

特殊形状的碰撞盒不在本篇文章的讨论范围。

3.为什么要学习如何编写碰撞检测

问题:Unity已经有了自带的2D 和 3D 碰撞体以及一套完整且成熟的物理系统,我们为什么不能直接使用Unity自带的,反而还要去编写这个系统。

答:问的好。当你看到这篇文章的时候,说明你的心中已经有了准确的答案。不然也不会进到这篇文章中。
首先肯定是Unity的物理系统,无法满足我们的特殊需求。
那特殊需求都有哪些呢?

  • 1.我们需要编写一套基于定点数的碰撞检测系统。

  • 2.我们不想用Unity的碰撞检测,想自己编写一套属于自己的碰撞系统。

  • 3.纯纯个人兴趣,来学习如何碰撞系统的检测。

相信肯定是第一种占的人数比较多。

既然有需求,那就满足你们。

4.2D BOX & BOX 碰撞检测原理和代码

aabb盒碰撞检测,unity,游戏引擎

首先说下2D场景下 BOX&BOX碰撞的原理:

由于AABB碰撞是基于坐标轴对齐的,所以我们检测起来就非常简单。只需要检测两个碰撞盒是否有重合即可,也就是X轴和Y轴上是否有重合或相交。

判断原理:我们只需要检测第一个物体的最右的点是否大于第二个物体的最左侧的点,并且第二个物体的最右侧的点是否大于第一个物体的最左侧的点。Y轴检测原理也是如此

检测原理示意图如下:
aabb盒碰撞检测,unity,游戏引擎
BOX&BOX碰撞检测源码:

public class FixIntBoxCollider2D : FixIntCollider2D
{
	public float x { get { return transform.position.x; } }
    public float y { get { return transform.position.y; } }
    public Vector2 size = new Vector2(1, 1);
    public Vector2 conter;
    protected float mBoxWidth { get { return size.x / 2; } }
    protected float mBoxHeigth { get { return size.y / 2; } }
    public override bool DetectionBoxCollider(FixIntBoxCollider2D target)
    {
        //第一个物体的最右侧是否大于第二个物体的最左侧 并且 第二个物体的最右侧是否大于第一个物体的最左侧;
        bool isCollider_x = x + mBoxWidth >= target.x - target.mBoxWidth
            && target.x + target.mBoxWidth >= x - mBoxWidth;

        bool isCollider_y = y + size.y >= target.y - target.mBoxHeigth
           && target.y + target.mBoxHeigth >= y - mBoxHeigth;

        return isCollider_x && isCollider_y;
    }
}

5.2D BOX &Shpere 碰撞检测原理和代码

aabb盒碰撞检测,unity,游戏引擎

BOX与Shpere碰撞检测相较于 BOX&BOX 以及 Shpere&Shpere碰撞检测就稍微复杂一点。 不过也不是特别复杂,因为博主已经给大家画好了碰撞检测流程图,以及碰撞检测计算公式。

其实我们都只到,当球体与BOX平行X轴或Y轴时,我们只需要计算二者之间的半径即可检测出是否发生重叠和相交。
BOX与Shpere碰撞检测主要复杂在当一个球形碰撞盒处于BOX碰撞盒边角时的处理。
这个时候我们已经不能单纯的通过二者之间的距离和半径去判断是否发生碰撞了。因为BOX从中心点到边角的距离是大于BOX的半径的。所以单纯这样检测是不准的。

而准确的做法是获取Shpere球体距离BOX最近的处于BOX碰撞盒上的一个点。然后在由球体半径减去该点得出向量长度,最后计算该向量是否<球体半径,若小于则产生碰撞,否则说明两个碰撞体不重叠。

关于BOX距离球体最近的一个点获取原理:

1.P.y获取原理: (P点如下图位置)

首先获取 球体A的Y点,称作为A.y。
然后获取BOX碰撞体D的Y点坐标。称作为D.y。
A.y-D.y 就得到了一个值Y_Dis。当然这个值可能是大于Box的高度的。也就是超出了Box碰撞盒的区域。所以我们需要通过Clamp(Y_Dis,-D.height/2,D.height/2)强制限制该值,让该值处于Box碰撞盒的范围之内。然后用D.y+Y_Dis就得到了P.y。
通过这种方式我们就得到了P.y。然后就是获取P.x

2.P.x获取原理:
首先获取 球体A的X点坐标,称作为A.x。
然后获取BOX碰撞体D的X点坐标。称作为D.x。
A.x-D.x 就得到了一个值X_Dis。当然这个值也是可能是大于Box的宽度的。也会超出Box碰撞盒的区域。所以我们需要通过Clamp(X_Dis,-D.Width/2,D.Width/2)强制限制该值,让该值处于Box碰撞盒的范围之内。然后用D.x+X_Dis就得到了P.x。
通过这种方式我们就得到了P.x。

通过上面两步我们就得到了距离 Shpere球体A 最近的一个处于BOX碰撞盒上的一个点P。

最后用球体的位置减去P点的位置得出一个向量。这个向量如果小于 Shpere球体A 的半径,则说明发生了碰撞。

碰撞原理和计算公式如下图:

aabb盒碰撞检测,unity,游戏引擎
BOX &Shpere 碰撞检测代码

public class FixIntBoxCollider2D : FixIntCollider2D
{
	public float x { get { return transform.position.x; } }
    public float y { get { return transform.position.y; } }
    public Vector2 size = new Vector2(1, 1);
    public Vector2 conter;
    protected float mBoxWidth { get { return size.x / 2; } }
    protected float mBoxHeigth { get { return size.y / 2; } }
  
    public override bool DetectionSphereollider(FixIntSphereCollider2D target)
    {
        float xDis = target.x - x;
        float p_x = Mathf.Clamp(xDis, -mBoxWidth, mBoxWidth);

        float yDis = target.y - y;
        float p_y = Mathf.Clamp(yDis, -mBoxHeigth, mBoxHeigth);

        Vector2 closePoint = new Vector2(x+p_x,y+p_y);
        return Vector2.Distance(target.transform.position,closePoint)<=target.radius;
    }
}

6.2D Shpere &Shpere 碰撞检测代码

aabb盒碰撞检测,unity,游戏引擎
球体与球体的碰撞就在简单不过了,只需要判断半径即可。
原理就是判断A与B之间的向量是否 <= A.radius+B.raduis。小于则说明产生碰撞,大于则不碰撞。

public class FixIntSphereCollider2D : FixIntCollider2D
{
    public float radius;
    public float x { get { return transform.position.x; } }
    public float y { get { return transform.position.y; } }
    
    public override bool DetectionSphereollider(FixIntSphereCollider2D target)
    {
        // 判断A与B之间的向量是否 <= A.radius+B.raduis。小于则说明产生碰撞,大于则不碰撞。
        bool isCollider = Vector2.Distance(transform.position,target.transform.position)  <= (radius + target.radius) ;
        return isCollider;
    }
    public override bool DetectionBoxCollider(FixIntBoxCollider2D target)
    {
        throw new System.NotImplementedException();
    }
}

文章来自于铸梦老师,铸梦之路系列课程。
想了解更多框架、帧同步技术、UGUI优化相关技术可在企鹅kt搜索 铸梦xy。文章来源地址https://www.toymoban.com/news/detail-602507.html

到了这里,关于【Unity 2D AABB碰撞检测】铸梦之路的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [Unity学习日志]用Collider2D.IsTouchingLayers()进行碰撞检测

    复健,跟麦扣老师的教程注意到的新方法 Unity2018教程2D入门:07 跳跃动画 LayerMask_哔哩哔哩_bilibili 目的是检测玩家是否落地,然后切换动画 自己的实现就是简单的检测速度: 麦扣老师的方法:检测玩家是否与地面这个Layer产生碰撞,产生碰撞即落地 具体步骤: 1.将Tilemap图层设

    2023年04月22日
    浏览(47)
  • unity-2D游戏地面检测 三射线检测

        2D游戏中跳跃是不可或缺的功能,要实现跳跃功能,就必须进行地面检测!常规方法是使用一根往角色下方延伸的射线检测,但是这种方法在一些复杂不规则的地面效果通常不尽人意。通过增加射线数量,即可完善这种方法的不足,达到在复杂地面也能正确检测角色是否

    2024年02月15日
    浏览(39)
  • 2022版本unity-2D游戏官方案例--带视频案例(1)(层级渲染,物理碰撞,粒子动画,UI等多位基础一体化)

      👨‍💻个人主页:@元宇宙-秩沅 hallo  欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由  秩沅  原创 收录于专栏 unity实战入门  ⭐相关文章⭐ ——————————————————— -[本站最全-unity常用API大全(万字详解),不信你不收藏] -[关于游戏剧情模式中用到的

    2024年02月03日
    浏览(66)
  • Unity 2d - 基础 - 碰撞(一) - 针对性碰撞

    问题: 在开发过程中经常会遇到物体碰撞的问题,比如玩家的角色遇到敌人后碰撞掉血,子弹碰到敌人后消失等等。 一般我们会选择添加刚体与碰撞盒来处理此类问题,但添加碰撞盒后,玩家的多个单位之间也会形成碰撞,在横版2D游戏中就很致命了,如图:  要处理此问题

    2024年02月16日
    浏览(37)
  • Unity之2D碰撞器

    1、什么是碰撞器 碰撞器是用于在物理系统中 表示物体体积的的(形状或范围) 刚体通过得到碰撞器的范围信息进行计算 判断两个物体的范围是否接触 如果接触 刚体就会模拟力的效果产生速度和旋转 2、参数 Edit Collider:编辑碰撞器 Material:一种物理材质,用于确定碰撞的

    2024年02月15日
    浏览(49)
  • Unity 2D点击事件、碰撞

    1.事件封装 定义脚本,实现事件相关接口即可 2.点击对象必须要添加BoxCollider2D脚本 3.摄像机上必须添加Physics2DRaycaster脚本 4.GameInputEvent2D 事件必须添加在挂载Physics2DRaycaster的对象及其父类身上。 5.如果要有碰撞或者触发器回调,碰撞其中之一要添加Rigidbody2D脚本,且不能设置

    2024年02月09日
    浏览(37)
  • Unity 实现2D地面挖洞!涂抹地形(碰撞部分,方法二)

    老规矩先上效果图 继上一篇涂抹地形文章讲解发出后,有不少网友私信找我要原码,也有部分网友觉得太复杂了难以实现。关于原码因为这个Demo最初始的原码弄不见了,还有就是代码本身用在了公司的游戏项目中加了很多项目相关的逻辑,我不知道能不能分享所以没有直接

    2024年02月06日
    浏览(45)
  • 关于unity中碰撞盒Collider2D中的Layer Overrides属性

    层碰撞矩阵 edit -》 project settings -》physics 2d 配置好一个GameObject之后,设置它的Layer 仅给当前Collider添加可碰撞的额外层。所以当前Collider发生碰撞or触发的层为: 层碰撞矩阵 + include layers 。 仅给当前Collider移除可碰撞的额外层。当前碰撞层级: 层碰撞矩阵 - exclude Layers 。 默

    2024年04月27日
    浏览(41)
  • Unity碰撞器检测失败

    1.1tag错误 看看是不是误删tag或者tag改变导致碰撞器无法检测 2.1无法触发碰撞检测方法 2.1.1 OnCollisionEnter、OnTriggerEnter、OnTriggerStay方法 OnCollisionEnter:检测与被检测方都应有Collider或者Rigibody,如果都有Rigibody,需勾选isKinematic。 OnTriggerEnter:检测与被检测方至少有一个Rigibody(

    2024年02月20日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包