Unity - Ray射线检测_overlapspherenonalloc-程序员宅基地

技术标签: Unity3D  Unity  射线检测  

一:射线

Ray射线

定义:射线是一条从原点出发,沿某一方向运动的无限直线。

//创建一条初始位置为startPos,方向为dir的一条射线
Ray ray = new Ray (startPos, dir);

//创建一条从摄像机通过屏幕点的光线。
//得到的光线在世界空间中,从相机的近平面开始,经过屏幕上的(x,y)像素坐标(位置)。z是忽略。
Ray camerRay = Camera.main.ScreenPointToRay (Input.mousePosition);

RaycastHit : 用于存储发射射线后产生的碰撞信息。

常用的成员变量如下:

  • collider 与射线发生碰撞的碰撞器
  • distance 从射线起点到射线与碰撞器的交点的距离
  • normal 射线射入平面的法向量
  • point 世界空间中射线与碰撞体的交点的坐标(Vector3对象)

具体的可以参考官方文档

二:线性投射

1.Raycast :

从起点开始,向最大距离的方向发射一条射线,进行碰撞检测,但是仅能检测到第一个被射线碰撞的物体。
可以选择提供一个 LayerMask 来过滤掉不需要的碰撞,结合RaycastHit可以获取到碰撞信息。

定义:

public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance, int layerMask);

有多个重载方法,具体参考官方文档

示例代码:

Ray ray = new Ray (startPos, dir);
RaycastHit hit;
Physics.Raycast(ray,out hit,distance);
//或者
Physics.Raycast(startPos,dir,out hit,distance);
Physics.Raycast(ray,out hit,distance,LayerMask.GetMask("ball"));

如图:
在这里插入图片描述
ps: 对于射线的调试可以用 Debug.DrawRay() 或者 Gizmos 来绘制射线,方便调试。
如:Debug.DrawRay(startPos,dir,Color.red);

2.RaycastAll :

用法和Raycast差不多,区别在于可检测射线路径上的所有物体,返回一个RaycastHit[ ]
示例代码:

//检测所有
RaycastHit[] hits = Physics.RaycastAll(ray,distance);
RaycastHit[] hits = Physics.RaycastAll(ray,distance,LayerMask.GetMask("ball"));

3.Linecast:

如果有任何碰撞器与start和end之间的直线相交,返回true,否则false
示例代码:

//两点检测: 如果有任何碰撞器与start和end之间的直线相交,返回true,否则false
bool isCrash = Physics.Linecast(startPos,endPos);
bool isCrash = Physics.Linecast(startPos,endPos,LayerMask.GetMask("ball"));

三:体型投射

1.BoxCast 立方体投射:

将方框沿射线投射,进行立方体范围碰撞检测,返回一个bool值。
和Raycast 一样只能检测第一个(ps : BoxCastAll 检测所有, 用法和BoxCast类似)

定义:以center为中心创建一个大小为halfExtents的立方体线框,向direction方向发射,最大距离为maxDistance,根据layerMask过滤碰撞体,并且通过queryTriggerInteraction指定此查询是否应触发触发器,hitInfo接收碰撞信息

//以center为中心创建一个半径大小为halfExtents的立方体线框,向direction方向发射,最大距离为maxDistance,根据layerMask过滤碰撞体,并且通过queryTriggerInteraction指定此查询是否应触发触发器,hitInfo接收碰撞信息
public static bool BoxCast(Vector3 center, Vector3 halfExtents, Vector3 direction, out RaycastHit hitInfo, [Internal.DefaultValue("Quaternion.identity")] Quaternion orientation, [Internal.DefaultValue("Mathf.Infinity")] float maxDistance, [Internal.DefaultValue("DefaultRaycastLayers")] int layerMask, [Internal.DefaultValue("QueryTriggerInteraction.UseGlobal")] QueryTriggerInteraction queryTriggerInteraction);

示例代码:

Ray ray = new Ray (startPos, dir);
RaycastHit hit;
bool isCrash = Physics.BoxCast(startPos,transform.localScale/2,dir,out hit);
bool isCrash = Physics.BoxCast(startPos,transform.localScale/2,dir,out hit,transform.rotation,distance,LayerMask.GetMask("ball"));

如图:
在这里插入图片描述

2.SphereCast 球体投射:

和立方体投射类似,范围为球体,返回一个bool值,单一检查。(SphereCastAll:检测所有,返回RaycastHit[])
定义:以origin为中心创建一个半径为radius的球体线框,向direction方向发射,最大距离为maxDistance,根据layerMask过滤碰撞体,并且通过queryTriggerInteraction指定此查询是否应触发触发器。

public static bool SphereCast(Vector3 origin, float radius, Vector3 direction, out RaycastHit hitInfo, [Internal.DefaultValue("Mathf.Infinity")] float maxDistance, [Internal.DefaultValue("DefaultRaycastLayers")] int layerMask, [Internal.DefaultValue("QueryTriggerInteraction.UseGlobal")] QueryTriggerInteraction queryTriggerInteraction);

示例代码:

Ray ray = new Ray (startPos, dir);
RaycastHit hit;
bool isHit = Physics.SphereCast (startPos, transform.localScale.x/2, dir, out hit, m_MaxDistance);

演示:
在这里插入图片描述

3.CapsuleCast 胶囊体投射:

和上面两种类似,检测范围为胶囊体,返回一个bool值,单一检查。(CapsuleCastAll:检测所有,返回RaycastHit[])
定义:point1胶囊体顶端的球体中心,point2胶囊体末端的球体中心,半径为radius,向direction方向发射,最大距离为maxDistance,根据layerMask过滤碰撞体,并且通过queryTriggerInteraction指定此查询是否应触发触发器。

public static bool CapsuleCast(Vector3 point1, Vector3 point2, float radius, Vector3 direction, out RaycastHit hitInfo, [Internal.DefaultValue("Mathf.Infinity")] float maxDistance, [Internal.DefaultValue("DefaultRaycastLayers")] int layerMask, [Internal.DefaultValue("QueryTriggerInteraction.UseGlobal")] QueryTriggerInteraction queryTriggerInteraction);

示例代码:

RaycastHit hit;
bool isHit = Physics.CapsuleCast(point1, point2,radius, direction, out hit, maxDistance, layerMask, queryTriggerInteraction);

四:相交检测

注意:"相交检测” 每个方法都有对应的 “无内存分配” 方法,每次调用该方法时都是读取缓存,不会重新分配内存,也就是说不会产生过多的内存垃圾。实际应用中也尽量采用“无内存分配”方法,可以提高一定性能。

比如:
OverlapBox 对应的 “无内存分配” 方法:OverlapBoxNonAlloc
OverlapSphere 对应的 “无内存分配” 方法:OverlapSphereNonAlloc
OverlapCapsule 对应的 “无内存分配” 方法:OverlapCapsuleNonAlloc

这些用法区别不大,详情可以查看官网

1.OverlapBox 相交立方体:

用于检测与立方体碰撞的所有collider信息。

**定义:以center为中心创建一个半径为halfExtents的正立方体,通过layerMask过滤不需要的collider。返回一个collider集合 Collider[] **

public static Collider[] OverlapBox(Vector3 center, Vector3 halfExtents, Quaternion orientation, int layerMask);

演示:
在这里插入图片描述

2.OverlapSphere 相交球:

用于检测与球体碰撞的所有collider信息。

**定义:以center为中心创建一个半径为radius的球体,通过layerMask过滤不需要的collider。返回一个collider集合 Collider[] **

public static Collider[] OverlapSphere(Vector3 position, float radius, [Internal.DefaultValue("AllLayers")] int layerMask, [Internal.DefaultValue("QueryTriggerInteraction.UseGlobal")] QueryTriggerInteraction queryTriggerInteraction);

3.OverlapCapsule 相交胶囊体:

用于检测与胶囊体碰撞的所有collider信息。
和以上类似

定义:

public static int OverlapCapsuleNonAlloc(Vector3 point0, Vector3 point1, float radius, Collider[] results, [Internal.DefaultValue("AllLayers")] int layerMask, [Internal.DefaultValue("QueryTriggerInteraction.UseGlobal")] QueryTriggerInteraction queryTriggerInteraction);

五:校验检测

相交检测类似,区别在于该类型方法 校验是否发生了碰撞 ,返回的是bool值,而不是碰撞体信息集合,相对于性能较好。(ps:也会校验自身的collider)

1.CheckBox 校验立方体:

校验该立方体是否与其他collider重叠。返回bool值

定义:

public static bool CheckBox(Vector3 center, Vector3 halfExtents, Quaternion orientation = Quaternion.identity, int layermask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);

2.CheckSphere 校验球:

校验该是否与其他collider重叠。返回bool值

定义:

public static bool CheckSphere(Vector3 position, float radius, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);

3.CheckCapsule 校验胶囊体:

校验该立方体是否与其他collider重叠。返回bool值

定义:

public static bool CheckCapsule(Vector3 start, Vector3 end, float radius, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);

IgnoreCollision 忽略碰撞:

使碰撞检测系统忽略collider1和collider2之间的所有碰撞。
这对于防止投射物与发射它们的物体发生碰撞是很有用的。

public static void IgnoreCollision(Collider collider1, Collider collider2, bool ignore = true);

六:调试技巧:

一般有两种方法:

1.Debug.DrawRay:绘制一条射线。
示例:

//start:起点,dir:射线的方向和长度, red:颜色
Debug.DrawRay(start,dir,Color.red);

2. Gizmos:用于在场景视图中提供可视化调试或设置帮助。(以上的演示动态图就是通过该方法绘制的)

示例:

 void OnDrawGizmos () {
    
 //设置颜色
 Gizmos.color = Color.red;
 //绘制射线
 Gizmos.DrawRay (transform.position, transform.forward * distance);
 //绘制立方体线框
 Gizmos.DrawWireCube (transform.position + transform.forward * distance, transform.localScale);
}

最后

引用网友HONT的性能测试总结:

射线和线段的开销非常小,可以忽略。

性能消耗顺序:

从投射物来看: Box < Sphere < Capsule
从投射方法来看: CheckXXX < OverlapXXX < XXXCast

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_28299311/article/details/103120607

智能推荐

攻防世界_难度8_happy_puzzle_攻防世界困难模式攻略图文-程序员宅基地

文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文

达梦数据库的导出(备份)、导入_达梦数据库导入导出-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作  导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释:   cwy_init/init_123..._达梦数据库导入导出

js引入kindeditor富文本编辑器的使用_kindeditor.js-程序员宅基地

文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js

STM32学习过程记录11——基于STM32G431CBU6硬件SPI+DMA的高效WS2812B控制方法-程序员宅基地

文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6

计算机网络-数据链路层_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输

软件测试工程师移民加拿大_无证移民,未受过软件工程师的教育(第1部分)-程序员宅基地

文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...

随便推点

Thinkpad X250 secure boot failed 启动失败问题解决_安装完系统提示secureboot failure-程序员宅基地

文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure

C++如何做字符串分割(5种方法)_c++ 字符串分割-程序员宅基地

文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割

2013第四届蓝桥杯 C/C++本科A组 真题答案解析_2013年第四届c a组蓝桥杯省赛真题解答-程序员宅基地

文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答

基于供需算法优化的核极限学习机(KELM)分类算法-程序员宅基地

文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。

metasploitable2渗透测试_metasploitable2怎么进入-程序员宅基地

文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入

Python学习之路:从入门到精通的指南_python人工智能开发从入门到精通pdf-程序员宅基地

文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf

推荐文章

热门文章

相关标签