stonstad 发表于 2022-3-11 21:33

【唐老狮】Unity——物理系统(射线检测)

【学习目标】


[*]射线检测

[*]能够通过射线检测进行碰撞判断
[*]能够通过玩家点击屏幕检测选中的物体
<hr/>【射线检测】


[*]作用
可以利用3D世界中的射线,和3D世界中的物体进行碰撞(相交)判断,利用它可以实现射击



[*]必要条件
碰撞体
射线
<hr/>【3D世界中射线】

由线段的一端无限延长所形成的直的线,由起点和方向两个关键属性构成



代码中创建射线对象



代码中创建射线对象



注意:这里画的是线段,用来看射线的方向的,真的射线是从起点向方向无限延伸的

<hr/>【屏幕发出的射线】

根据玩家在屏幕上点击的位置,发射一条射线



代码中创建屏幕射线



代码中创建屏幕射线


<hr/>【射线总结】

单独的射线,对于我们来说没有意义,它一定是和别的模块配合使用的
<hr/>【射线碰撞检测】

Unity提供的物理类
Physics
其中提供射线检测相关方法



以上是Physics物理类提供的射线检测方法,我们选择几个最常用的方法进行讲解,学会了它们基本就学会了所有方法


[*]射线检测获取相交的单个物体
bool Raycast(Ray ray, out RaycastHit hitInfo)
bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance)
bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance, int layerMask);
[*]射线检测获取相交的多个物体
RaycastHit[] RaycastAll(Ray ray, float maxDistance);
RaycastHit[] RaycastAll(Ray ray, float maxDistance, int layerMask);
[*]参数含义
Ray——射线对象
maxDistance——射线检测的最大距离
RaycastHit——碰撞(相交)对象信息
layerMask——层蒙版(用于只检测特定层对象)
[*]返回值含义
bool——当射线和物体相交时返回true
RaycastHit[]——当射线和物体相交时,返回相交的物体们,如果没有碰撞到,数组长度为0
<hr/>【实例】


[*]Raycast(Ray ray, out RaycastHit hitInfo)





在游戏界面中点击鼠标,当点击Panel时射线检测成功,打印了它的名字


[*]RaycastHit[] RaycastAll(Ray ray, float maxDistance);





在游戏界面中点击鼠标,当点击红色方块时,射线检测会穿透方块和平面,所以打印出了2个名字信息(前提是maxDistance足够大

<hr/>

[*]完成目标一
   能够通过射线检测进行碰撞判断

[*]完成目标二
   能够通过玩家点击屏幕检测选中的物体
<hr/>【关键参数layerMask】

该参数可以让射线检测只检测指定层级的对象



把场景上的Cube层级改为Cube(没有就Add Layer新建一个自定义层)



将刚才的代码加一个参数



这时运行你发现只会打印Cube的名字


Panel没有被射线检测到,这是因为我们填了层蒙版参数
↓↓↓↓
↓↓↓↓


LayerMask.NameToLayer(层名)
是Unity提供给我们的一个根据层名字转换为层编号的方法
↓↓↓↓
↓↓↓↓
层编号是什么?





Unity中最多可以有32个层,编号从0~31

↓↓↓↓
↓↓↓↓
我们通过LayerMask.NameToLayer(层名)得到一个0~31的层编号,之后将 1 左移 “层编号”位。也就是说0~31每一个层都会对应一个唯一的2进制数,并且这个数是2的n次方。


你只需要记住


是固定写法
通过它来确定层
↓↓↓↓
↓↓↓↓
如果要检测多个层如何写?


由于2进制的特性,想要检测多隔层,只需要把不同层进行 位或 运算即可
<hr/>【总结】


[*]普通射线
new Ray
[*]屏幕射线
Camera.main.ScreenPointToRay(Input.mousePosition)
[*]射线检测
Physics中的函数
[*]关键参数
1 << LayerMask.NameToLayer("层名")
<hr/>关注唐老狮获取更多干货内容
页: [1]
查看完整版本: 【唐老狮】Unity——物理系统(射线检测)