本文首发于洪流学堂微信公众号。
洪流学堂,学Unity快人几步
你好,我是郑洪智,你的技术探路者。
这周三我们直播剖析了Unity中射线检测的功能,以下是直播内容精华部分笔记。
完整录播:https://www.bilibili.com/video/av24468720
源码地址:https://github.com/zhenghongzhi/PhysicRaycast
什么是射线(Ray)?
射线检测能用来做什么?
- 检测光标位置的三维物体
- 检测角色前面的物体(自动开门)
- 从空中向下检测(凹凸不平的地形的瞬移)
- 测量距离(激光测距)
- ……
API
public static bool Raycast(Ray ray, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);
public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);
public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);
public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);
其实你只要记住调用是使用 Physics.Raycast()
就行啦
参数RaycastHit
可以获取到射线碰撞后的一些参数。
常用的有:
- collider 射线检测到的collider,这个非常常用,因为能根据collider.gameObject获取到对应GameObject
- distance 射线发射源与检测到的位置的距离
- normal 射线碰撞位置的法线
- point 射线碰撞位置的世界坐标
- transform 射线碰撞物体的transform组件
LayerMask参数
LayerMask是一个比较难懂的参数
Layer与LayerMask的关系
Layer是0-31的数字
LayerMask是按位对应0-31
如Layer9:Enemy
LayerMask用二进制表示:00000000 00000000 000000**1**0 00000000
从右往左第10位,等于表达式:1<<9
这是一种二进制思想,使用mask(掩码)表示时,可以同时表示多个状态的有无。
二进制思想小测验
1000 个瓶子中有一瓶毒药,一只老鼠吃到毒药一周之内会死,如果要在一周之内检测出有毒药的一瓶,问至少需要几只老鼠?
A 8
B 10
C 32
D 999
洪流学堂公众号 回复 老鼠 获取答案
如何根据Layer获取LayerMask
如果你知道Layer的名字,可以通过LayerMask.GetMask()方法获取,注意这个方法可以传入一个或多个string类型参数。
int mask = LayerMask.GetMask("Player", "NPC");
如果你知道Layer的数字,比如Layer9,可以通过移位操作1<<9来获取
int playerMask = 1<<9;
int npcMask = 1<<10;
int mask = playerMask | npcMask; // 通过位操作“或(|)”同时检测player 和 npc层
int reverse = ~mask; // 通过位操作"求反(~)",检测除了player 和 npc的其他层
调试小技巧
使用Debug.DrawRay()方法可以在Scene中画出射线或者检测到的位置,更好的方便调试。
小结
本周直播的精华内容笔记如上,直播通知QQ群:492325637。
洪流学堂公众号内回复log可以获取最新调试插件的下载地址。
你有没有朋友遇到过射线检测的问题?你可以把今天的内容分享给他,或许你能帮到他。