文章原链接:
【唐老狮】Unity——物理系统(射线检测) - 哔哩哔哩 (bilibili.com)
射线检测:碰撞判断、检测玩家点击的物体
判断射线与物体是否碰撞:碰撞体、射线
//声明射线
Ray r = new Ray(起点,终点);
Ray r = Camera.main.ScreenPointToRay(Input.position);
//射线碰撞
Physics 类 Raycast 函数 RaycastHit 参数类 返回值为bool或RaycastHit[]
if(Phsics.Raycast(Ray r,out RaycastHit hitinfo,float maxDistance,int layerMask);)
RaycastHits[] hitInfos = Physics.Raycast(Ray r,float maxDistance,int layerMask);
//画出射线
Debug.DrawRay(r.origin,r.direction);
一、射线类型
3D世界的射线
决定因素:起点、方向。 无限延伸
Ray r = new Ray()
Ray r = new Ray(Vector3.zero,Vector3.forward);
//画出射线
Debug.DrawRay(Vector3.zero,Vector3.forward);
屏幕发出的射线
决定因素:起点:玩家点击的屏幕上的一点。方向:垂直屏幕
Ray r = Camera.main.ScreenPointToRay();
Ray r = Camera.main.ScreenPointToRay(Input.position);
//画出射线
Debug.DrawRay(r.origin,r.direction);
二、射线应用
2.1 射线碰撞检测
关键类:Physics 关键函数:Raycast() 关键参数类:RaycastHit
射线检测获取相交的单个物体
bool Raycast(Ray r,out RaycastHit hitinfo);
bool Raycast(Ray r,out RaycastHit hitinfo,float maxDistance);
bool Raycast(Ray r,out RaycastHit hitinfo,float maxDistance,int layerMask);
//返回:是否发生碰撞
射线检测获取相交的多个物体
RaycastHitp[] Raycast(Ray r,float maxDistance);
RaycastHitp[] Raycast(Ray r,float maxDistance,int layerMask);
//返回:返回被射线碰撞的物体。未碰撞:数组长度为0
参数含义
Ray:射线对象
RaycastHit:碰撞(相交)对象信息
maxDistance:射线检测最大距离
layerMask:层蒙版(用于检测指定层的对象)
2.2 关键参数:layerMask
作用:只检测指定层级的对象
private Ray r;
public RaycastHit hitInfo;
Physics.Raycast(r,hitInfo,1 << LayerMask.NameToLayer("Cube"));
1 << LayerMask.NameToLayer(“Cube”) -> 根据层面转换为层编号
Unity最多有32个层,编号0~1。每一层对应唯一的2进制数,2的n次方
![[Pasted image 20240708235823.png]]
同时包含多个层:位或 |运算
1 << LayerMask.NameToLayer(“Cube”) | 1 << LayerMask.NameToLayer(“Panel”)
三、实例
检测是否发生碰撞
private Ray ray;
private RaycastHit hitInfo;
void Update(){
if(Input.GetMouseDown(0)){
ray = Camera.main.ScreenPointToRay(Input.mouseposition);
if(Physica.Raycast(ray,out hitInfo,1000))
Debug.Log(hitInfo.collider.name)
}
}
鼠标的点击只响应UI层、Cube层
private Ray ray;
private RaycastHit[] hitInfos;
void Update(){
if(Input.GetMouseButtonDown(0)){
ray = Camera.main.ScreenPointToRay(Input.mousePosition)
hitInfos = Physics.Raycast(ray,1000,
1 << LayerMask.NameToLayer("UI") | ! << LayerMask.NameToLayer("Cube"));
for(int i=0;i<hitInfo.Length;i++)
Debug.Log(hitInfos[i].collider.name)
}
}