当前位置: 首页 > news >正文

【unity技巧】Physics2D Raycast、Overlapcircle、OverlapBox检测的用法

文章目录

  • 分析
  • 检测地面
    • 1. 使用Raycast
      • 1.1 介绍
      • 1.3 场景窗口可视化
      • 1.4 完整实例代码
      • 1.4 存在问题
        • 1.4.1 问题1
        • 1.4.2 问题2
    • 2. 使用Overlapcircle
      • 2.1 介绍
      • 2.2 场景窗口可视化
      • 2.3 完整实例代码
      • 2.4 存在问题
    • 3. 使用OverlapBox
      • 3.1 介绍
      • 3.2 场景窗口可视化
      • 3.3 完整实例代码
      • 3.4 注意事项
  • 扩展
  • 参考

这里我以角色跳跃为例,实现角色是否在地面判断的3种方法,及优缺点

分析

通常我们不希望角色可以进行无限次的跳跃
比如如何让角色仅仅一次的跳跃呢?
我们的思路是对这个角色进行一次检测,当角色接触到了平台或者地面时,我们才允许角色跳跃
在这里插入图片描述
当角色是在空中时,角色不允许跳跃,直到落地为止

在这里插入图片描述

检测地面

我们如何去检测一个物体是否在地面上呢?

1. 使用Raycast

1.1 介绍

我们可以去使用Raycast方法(射线检测),让他发射一条向下的射线,如果这条射线能检测到任何添加了Collider组件的平台,那就意味着我们的角色接触地面了
在这里插入图片描述

Physics2D.Raycast(xxx, xx, xx);

方法第一个参数为射线发射点
第二个参数 为射线的方向
第三个参数为射线的检测距离

检测距离我们不能写成无限长,检测的最大距离,应该是人物的中心点,到我们人物的【底部】再多出一点点的距离(一点点的距离我用0.1来表示),射线是从我们图片当中的中心点发出的
在这里插入图片描述
我们可以通过【sp.bounds.extents.y】直接获取这个整张图片一半高度
在这里插入图片描述

1.3 场景窗口可视化

为了能够在场景窗口种,可视化这条射线,我们可以通过Debug.DrawRay方法,参数传递的是射线的发射点和射线反向
在这里插入图片描述

1.4 完整实例代码

private void CheckGround()
{RaycastHit2D hitInfo = Physics2D.Raycast(transform.position, -transform.up, sp.bounds.extents.y + 0.1f);Debug.DrawRay(transform.position,-transform.up * (sp.bounds.extents.y + 0.1f), Color.red);if(hitInfo.collider != null)//我们检测到了平台{isGround = true;}else{isGround = false;}
}

1.4 存在问题

1.4.1 问题1

当Raycast进行检测时,游戏一开始第一个检测到的是它的本身,并不是平台,是含有collider组件的游戏对象,而且角色的这个collider组件又无法去除,导致检测一直是true

解决
在Start方法种,通过Physics2D.queriesStartInCokkiders=false,来忽略一开始射线检测的游戏内部collider组件

private void Start(){Physics2D.queriesStartInCokkiders=false;
}

1.4.2 问题2

在这里插入图片描述
如上图,当我们的平台靠的足够近时,并且小于角色的宽度时,我们的角色必然是可以站在这两个平台之间不会掉下去的,因为我们胖嘛,我们并不会掉下去,但是当我们想要再次进行跳跃的时候,由于Raycast射线的检测,在我们的射线路径中,检测判定为空,我们并没有检测到任何的collider组件,这也反映出了Raycast在进行检测时,带来的一些缺点和不足

2. 使用Overlapcircle

2.1 介绍

在检测平台跳跃时,我们通常并不会使用Raycst方法来检测人物是否着地,而是需要去给他一个【大小范围】的来检测。这次我们需要使用【Physics2D.OverlapCircle】方法,这个方法通过一个circle(圆形)区域去进行检测,如果检测到任何的collider的碰撞器组件对象,会返回collider2d类型的变量

Physics2D.OverlapCircle(xxx, xx, xx);

第一个参数是这个圆形的中心点位置
第二个参数是这个圆形的半径距离
第三个参数是这个圆形能够检测的【指定层】
在这里插入图片描述

2.2 场景窗口可视化

为了能够可视化的去看到,究竟我们这个圆形的检测范围是多大,OnDrawGizmos在方法的内部可视化一个子物体位置坐标为中心
OnDrawGizmos在方法内部可视化一个以子物体位置坐标为中心,检测长度为半径的圆形,这样我们就可以有通过Inspector窗口直接对这个圆形检测范围进行非常直观的调整
在这里插入图片描述
在这里插入图片描述

2.3 完整实例代码

private void CheckGround()
{Collider2D collider = Physics2D.OverlapCircle(checkPoint.position, checkRadius, layerMask);if(collider!=null)//我们检测到了平台isGround true;}else{isGround false;}
}private void OnDrawGizmos()
{Gizmos.DrawWireSphere(checkPoint.position, checkRadius);Gizmos.color = Color.red;
}

2.4 存在问题

在这里插入图片描述
如上图,比如我们站在平台的边缘,如果我们的圆形的半径不足够大的话,我们依然没有办法去进行判断,但是如果我们的半径足够大,满足我们人物的宽度时,会出现我们的角色没有真正到达地面,也判定为可以再次起跳
在这里插入图片描述

3. 使用OverlapBox

3.1 介绍

对于上面的问题,我们就引入了【Physics2D.OverlapBox】方法

Physics2D.OverlapBox(xxx, xxx, xx, xx);

检测的形状只是从圆形变为了box方形,
第二个参数就不是圆的半径了,而是一个Vector2结构类型的变量,表示这个检测方形的长和宽,
第三个参数表示的是角度,我设置为0即可
在这里插入图片描述

3.2 场景窗口可视化

因为检测形状发生了改变,如果你想在场景窗口种可视化,我们需要在OnDrawGizmos方法中,将【Sphere圆球】变成【Cube立方体
在这里插入图片描述
在这里插入图片描述

3.3 完整实例代码

private void CheckGround()
{Collider2D collider = Physics2D.OverlapBox(checkPoint.position, checkBoxSize, 0, layerMask);if(collider!=null)//我们检测到了平台isGround true;}else{isGround false;}
}private void OnDrawGizmos()
{Gizmos.DrawWireCube(checkPoint.position, checkBoxSize);Gizmos.color = Color.red;
}

3.4 注意事项

我们最好保证检测方形的大小不要太大,如果检测的方形很大的话,我们会导致如果我们连续按下空格键(及跳跃键),很可能在第二次跳跃时检测人物还在地面上。同时进行了两次跳跃,导致一些不必要的问题,比如跳跃过高等

在这里插入图片描述

扩展

【unity技巧】实现马里奥一样更具物理感的长按长跳与短跳
【Unity游戏开发教程】零基础带你从小白到超神19——射线检测

参考

BeaverJoe【视频】:更具物理感的长跳与短跳和Raycast缺点

http://www.lryc.cn/news/92035.html

相关文章:

  • 一、kafka入门
  • 公司新来一00后,真让人崩溃...
  • (1Gb)S28HS01GTGZBHA030/ S28HS01GTGZBHV033/ S28HS01GTGZBHA033 FLASH - NOR闪存器件
  • 苹果服务端通知v2处理(AppStore Server Notifications V2)
  • matlab 道路点云路缘石边界提取
  • 二叉树详解:带你掌握二叉树
  • LNMP网站框架搭建(编译安装)
  • 详解Servlet API
  • 【小白教程】Docker安装使用教程,以及常用命令!
  • TypeScript基础
  • QML学习二:Doxygen为qml工程生成代码文档
  • Vue 有哪些经典面试题?
  • pandas速学-DataFrame
  • 在任务与执行策略之间的隐性耦合
  • Spring Cloud Alibaba Nacos 构建配置中心
  • 华为OD机试真题 Java 实现【猴子爬山】【2023 B卷 100分】,附详细解题思路
  • 【19JavaScript for 循环】JavaScript for 循环:掌握重复执行的关键
  • MySQL学习(联结,组合查询,全文本搜索)
  • Nautilus Chain:独特且纯粹的创新型 Layer3
  • 十六、立方体贴图(天空盒)
  • UniAD:实现多类别异常检测的统一模型
  • Java 面试 | tcp ip http https(2023版)
  • 全志V3S嵌入式驱动开发(音频输出和音频录制)
  • 使用RP2040自制的树莓派pico—— [2/100] HelloWorld! 和 点亮LED
  • 康耐视In-Sight2800相机的使用
  • 驱动开发:内核封装WFP防火墙入门
  • python+vue校园快递代取系统的设计与实现3i0v9
  • C 语言详细教程
  • 函数重载与缺省参数
  • 线程引入的开销