unity射线碰撞检测+LayerMask的使用

本文详细介绍了Unity中射线的应用,包括射线的基本概念、常用API及其参数解释,并通过示例代码展示了如何实现射线碰撞检测及层掩码的设置。

射线在unity中是个很方便的东西,对对象查找、多用于碰撞检测(如:子弹飞行是否击中目标)、角色移动等提供了很大的帮助,在此做个总结与大家分享下 ,若有不足欢迎吐槽

好了,话补多说啦,直接进入主题:

 

射线:在unity中射线是由一个点向一个方向发射的一条无终点的线,在发射轨迹中与其他物体发生碰撞时,它将停止发射 。

 

相关API:

1、Ray Camera.main.ScreenPointToRay(Vector3 pos) 返回一条射线Ray从摄像机到屏幕指定一个点
2、Ray Camera.main.ViewportPointToRay(Vector3 pos) 返回一条射线Ray从摄像机到视口(视口之外无效)指定一个点
3、Ray 射线类
4、RaycastHit 光线投射碰撞信息
5、bool Physics.Raycast(Vector3 origin, Vector3 direction, float distance, int layerMask)

 

当光线投射与任何碰撞器交叉时为真,否则为假。

bool Physics.Raycast(Ray ray, Vector3 direction, RaycastHit out hit, float distance, int layerMask)

 

在场景中投下可与所有碰撞器碰撞的一条光线,并返回碰撞的细节信息()。

bool Physics.Raycast(Ray ray, float distance, int layerMask)

 

当光线投射与任何碰撞器交叉时为真,否则为假。

bool Physics.Raycast(Vector3 origin, Vector3 direction, RaycastHit out hit,float distance, int layerMask)

 

当光线投射与任何碰撞器交叉时为真,否则为假。

 

注意:如果从一个球型体的内部到外部用光线投射,返回为假。

 

参数理解:

  origin : 在世界坐标中射线的起始点

  direction: 射线的方向

  distance: 射线的长度

  hit: 使用c#中out关键字传入一个空的碰撞信息类,然后碰撞后赋值。可以得到碰撞物体的transform,rigidbody,point等信息。

  layerMask: 只选定Layermask层内的碰撞器,其它层内碰撞器忽略。 选择性的碰撞

 

6、RaycastHit[] RaycastAll(Ray ray, float distance, int layerMask)

投射一条光线并返回所有碰撞,也就是投射光线并返回一个RaycastHit[]结构体。

列子如下:

using UnityEngine;
using System.Collections;
public class RayTest : MonoBehaviour {
// Use this for initialization
void Start ()
{
mainCrma = Camera.main;
}
private Camera mainCrma;
private RaycastHit objhit;
private Ray _ray;
void Update ()
{
if (Input.GetMouseButtonDown(0))
{
_ray=mainCrma.ScreenPointToRay(Input.mousePosition);//从摄像机发出一条射线,到点击的坐标
Debug.DrawLine(_ray.origin,objhit.point,Color.red,2);//显示一条射线,只有在scene视图中才能看到
if (Physics.Raycast (_ray, out objhit, 100))
{
GameObject gameObj = objhit.collider.gameObject;
Debug.Log("Hit objname:"+gameObj.name+"Hit objlayer:"+gameObj.layer);
}
}
}
}

 

 

layerMask参数:

Raycast (ray : Ray, out hitInfo : RaycastHit, distance : float = Mathf.Infinity, layerMask : int = kDefaultRaycastLayers)

 

其实很简单:1 << 10 打开第10的层。

~(1 << 10) 打开除了第10之外的层。
~(1 << 0) 打开所有的层。
(1 << 10) | (1 << 8) 打开第10和第8的层。

 

列子如下:

using UnityEngine;
using System.Collections;
public class LayerMaskTest : MonoBehaviour {
// Use this for initialization
void Start ()
{
mainCrma = Camera.main;
mask = 1<<( LayerMask.NameToLayer("cube"));//实例化mask到cube这个自定义的层级之上。
}
//private LayerMask mask 1<<10;
private LayerMask mask;
private Camera mainCrma;
private RaycastHit objhit;
private Ray _ray;
void Update ()
{
if (Input.GetMouseButtonDown(0))
{
_ray=mainCrma.ScreenPointToRay(Input.mousePosition);//从摄像机发出一条射线,到点击的坐标
Debug.DrawLine(_ray.origin,objhit.point,Color.red,2);//划出射线,只有在scene视图中才能看到
if (Physics.Raycast (_ray,out objhit, 100, mask.value))
{
GameObject gameObj = objhit.collider.gameObject;
Debug.Log("Hit objname:"+gameObj.name+"--Hit objlayerName:"+LayerMask.LayerToName (10));
}
}
}
}

创建2个cube,一个layer设置为:cube 一个layer设置为:Default

运行如下:

 

 

=============================

Ray只有起点和方向.函数附加x距离内的条件。

用到的Raycast主要有两个:

Physics.Raycast:
作用于任何物体,可以加限定 只检测某layer层

RaycastHit hit;
if(Physics.Raycast(transform.position, Vector3.down,out hit, 1000f))

print("dawdddd");
RaycastHit hit;
if(Physics.Raycast(transform.position, Vector3.down,out hit, 1000f,8))

print("dawdddd");
Collider.Raycast:

只检测ray是否穿过该Collider

RaycastHit hit;
Ray ray= new Ray(transform.position,Vector3.down);
if(collider.Raycast(ray,out hit,100))

print("dawdddd");

 

注意:

(1)无论是哪种raycast检测,从物体内部穿到外面的,都不视为穿过。只有从物体外穿到里面的才视为穿过。
(2)可以绘制 可见线 来辅助开发

1.Debug.DrawLine(V3 start,V3 end);

2. Gizmos.DrawLine (可以在编辑模式下显示,可视化更强)

 

如果在scene的Gizmos选项下 勾选 3D Gizmos, 那么线段位于真实3D空间里,有前后遮挡。

 

如果不勾选,则gizmo永远在最前显示。

void OnDrawGizmos () {
Vector3 checkPos_a =transform.position + new Vector3(0,0,0.2f);
Gizmos.color = Color.green;
Gizmos.DrawLine(checkPos_a,checkPos_a + Vector3.down*15);
}

 

unity 检测碰撞;unity射线使用;unity加碰撞;unity射线检测碰撞;射线检测unity;unity射线坐标;unity raycast layer;unity 查找所有子物体;unity 射线从自身发射;unity碰撞检测;unity 碰撞检测 没反应;unity 点 射线;unity中的射线;unity射线移动;unity碰撞;碰撞点 unity;unity产生碰撞;unity碰撞之后;unity碰撞后不移动;unity 射线碰撞检测;unity 射线检测 范围;unity 坐标射线;unity layer raycast;unity查找子物体;unity发射射线

 

转载于:https://www.cnblogs.com/mimime/p/6926611.html

<think>好的,我现在要回答用户在Unity使用射线检测时是否需要被检测物体具有碰撞体组件的问题。首先,我需要回忆一下Unity射线检测的工作原理。根据之前学过的知识,射线检测(Raycast)是通过发射一条射线来检测与场景中物体的碰撞。 接下来,我需要确认碰撞体组件的作用。根据引用[2]提到,碰撞体定义了物体的形状,比如盒形、球形等,并且每个需要参与碰撞检测游戏对象都需要附加碰撞体组件。这说明,如果物体没有碰撞体,它可能不会被射线检测到。 然后,查看用户提供的引用内容,引用[1]提到RaycastHit的属性如collider和transform都是与射线碰撞的组件相关,这进一步说明射线检测依赖碰撞体的存在。引用[3]中的例子也使用LineRender和射线检测碰撞体的位置信息,说明实际应用中确实需要碰撞体。 此外,我需要考虑特殊情况,比如触发器(Trigger)。引用[2]指出,碰撞体可以是Trigger,虽然Trigger不会产生物理反应,但仍能检测到进入、停留和离开。但射线检测是否触发Trigger呢?通常,射线检测默认不会检测Trigger,除非在Physics.Raycast的参数中指定查询触发器。 总结起来,射线检测要检测到物体,该物体必须具有碰撞体组件,无论是Trigger还是非Trigger类型。如果物体没有碰撞体,射线将直接穿过,无法检测到碰撞点。 最后,生成相关问题,帮助用户深入理解,比如如何检测没有碰撞体的物体,或者如何设置射线检测Trigger等。</think>在Unity使用射线检测时,被检测物体**必须附加碰撞体组件(Collider)**,否则射线将无法检测到该物体[^2]。以下是具体说明: --- ### 射线检测与碰撞体的关系 1. **基本要求** 射线检测依赖碰撞体组件定义物体的物理边界。例如: - 若物体只有渲染组件(如Mesh Renderer)但没有$Box\ Collider$,射线会直接穿过该物体。 - 若物体附加了$Sphere\ Collider$,射线会根据球形边界计算碰撞点[^2]。 2. **触发器(Trigger)的特殊情况** - 即使碰撞体设为Trigger(不参与物理碰撞),射线仍可检测到它,但需在射线检测时通过参数显式启用: ```csharp Physics.Raycast(ray, out hitInfo, maxDistance, layerMask, QueryTriggerInteraction.Collide); ``` 3. **复合碰撞体与层级关系** - 子物体若有独立碰撞体,射线会单独检测到子物体的碰撞。 - 若父物体禁用碰撞体组件,子物体碰撞体仍可被检测。 --- ### 示例代码 ```csharp // 发射射线检测前方物体 Ray ray = new Ray(transform.position, transform.forward); RaycastHit hit; if (Physics.Raycast(ray, out hit, 100)) { Debug.Log("碰撞物体: " + hit.collider.name); // 依赖碰撞体组件[^1] } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值