Unity-物理系统之射线检测
什么是射线检测
解决以下问题:
- 鼠标选择场景上一物体
- FPS射击游戏(无弹道-不产生实际的子弹对象进行移动)
- 等需要判断一条线和物体的碰撞情况
它可以在指定点发射一个指定方向的射线
判断该射线与哪些碰撞器相交,得到对应对象
射线对象
单独的射线对于我们来说没有实际的意义,我们需要用它结合物理系统进行射线碰撞判断
3D世界中的射线
- 参数一:起点
- 参数二:方向
1 | Ray r = new Ray(Vector3.right, Vector3.forward); |
摄像机发射出的射线
屏幕位置 为起点
摄像机视口方向 为方向
1 | Ray r2 = Camera.main.ScreenPointToRay(Input.mousePosition); |
碰撞检测 API
射线检测也是瞬时的
执行代码时进行一次射线检测
最原始的射线检测
准备一条射线
1 | Ray r = new Ray(Vector3.zero, Vector3.forward); |
Physics.Raycast()
- 参数一:射线
- 参数二: 检测的最大距离 超出这个距离不检测
- 参数三:检测指定层级(不填检测所有层)
- 参数四:是否忽略触发器
UseGlobal
-使用全局设置Collide
-检测触发器Ignore
-忽略触发器 不填使用UseGlobal
- 返回值:bool 当碰撞到对象时 返回 true 没有 返回false
1 | if (Physics.Raycast(r, 1000, 1 << LayerMask.NameToLayer("Monster"), |
还有一种重载 不用传入 射线 直接传入起点 和 方向 也可以用于判断
1 | if (Physics.Raycast(Vector3.zero, Vector3.forward, 1000, |
获取相交的单个物体信息
物体信息类
通过RaycastHit类 我们得到得到 碰撞到的对象信息
还可以得到一些 碰撞的点 距离 法线等等的信息
1 | RaycastHit hitInfo; |
- 参数一:射线
- 参数二:
RaycastHit
是结构体 是值类型 Unity会通过out
在函数内部处理后 得到碰撞数据后返回到该参数中 - 参数三:距离
- 参数四:检测指定层级
- 参数五:是否忽略触发器
1 | if( Physics.Raycast(r, out hitInfo, 1000, 1<<LayerMask.NameToLayer("Monster"), |
同理 还有一种重载 不用传入 射线 直接传入起点 和 方向 也可以用于判断
获取相交的多个物体
Physics.RaycastAll()
可以得到碰撞到的多个对象,如果没有 就是容量为0的数组
- 参数一:射线
- 参数二:距离
- 参数三:检测指定层级
- 参数四:是否忽略触发器
1 | RaycastHit[] hits = Physics.RaycastAll(r, 1000, 1 << LayerMask.NameToLayer("Monster"), |
还有一种NonAlloc型的函数 返回的碰撞的数量 通过out得到数据
Physics.RaycastNonAlloc()
1 | RaycastHit[] hits; |
使用时注意的问题
注意:
距离、层级两个参数 都是int类型
当我们传入参数时 一定要明确传入的参数代表的是距离还是层级
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Escapeey`Blog!
评论