Unity引擎学习笔记之【射线检测操作】

射线检测Raycast

  • 射线检测是一种常用的技术,用于检测游戏中的碰撞、交互等情况。Unity提供了几种不同的射线检测方法,包括射线检测、球形射线检测和盒形射线检测。

一、发射一条射线

  • 向屏幕中某处发射一条射线,体现在3D游戏空间中,即从视角摄像机开始向着空间中指定的某处发射一条射线

1.射线的定义

  • Ray()是一个用于创建射线的构造函数。它有两个参数:

    1. origin(起点):射线的起始点坐标。

    2. direction(方向):射线的方向向量。

    • (1).固定的射线
    Ray ray = new Ray(Vector3.zero, Vector3.up);

    • (2).从摄像机发射
     // 创建一条射线,从摄像机位置发出,并沿着摄像机的正方向向着鼠标点击的方向进行射线检测
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

2.实现发射射线检测碰撞触发

    //声明一个碰撞信息类
    RaycastHit hitInfo;

    //碰撞检测事件
    bool res=Physics.Raycast(ray, out hitInfo);
    //如果有射线碰撞输出内容
    if(res)
    {
        // 如果射线与物体发生碰撞,可以通过hitInfo获取碰撞的相关信息
            Debug.Log("Hit object: " + hitInfo.collider.gameObject.name);
            Debug.Log("Hit point: " + hitInfo.point);
            Debug.Log("Hit normal: " + hitInfo.normal);
    }
  • hitInfo.normal:用于获取碰撞点的法线向量。返回的是一个单位向量(长度为1),如果需要使用具有不同长度的法线向量,可以根据需要进行缩放。

  • Physics.Raycast(ray, out hitInfo) 是在Unity中进行射线检测的常用函数之 一。它接受一个 Ray 类型的参数和一个 out RaycastHit 类型的参数,用于检测从 Ray 的起点开始沿着 Ray 的方向是否与场景中的物体相交,并将检测到的信息存储在 RaycastHit 对象中。

    • 具体来说,ray 参数是一条射线,它是从摄像机或其他位置发出的,它有一个起点和一个方向。hitInfo 参数是一个传出参数,用于存储检测到的信息,包括碰撞的物体、碰撞点的位置、碰撞表面的法线等。

    • 当调用 Physics.Raycast(ray, out hitInfo) 时,Unity会检测从 ray 的起点开始沿着 ray 的方向是否与场景中的物体相交,如果相交,则将检测到的信息存储在 hitInfo 中,然后返回 true。如果没有相交,则返回 false
      撞的物体、碰撞点的位置、碰撞表面的法线等。

    • 在使用 Physics.Raycast(ray, out hitInfo) 进行射线检测时,需要注意以下几点:
    1. 射线检测的结果只与场景中的物体相关,与摄像机和其他相关因素无关。
    2. 如果一条射线与多个物体相交,可以使用 Physics.RaycastAll 函数来获取所有的碰撞信息。
    3. 在使用 Physics.Raycast 进行射线检测时,需要保证射线的方向向量是归一化的,否则可能会出现意外的结果。

二 、发射多条射线

1.多条射线定义

    RaycastHit[] hitInfos=Physics.RaycastAll(ray);

2.检测特定距离100

    RaycastHit[] hitInfos=Physics.RaycastAll(ray,100);

3.只检测特定图层

    RaycastHit[] hitInfos=Physics.RaycastAll(ray,100,1<<10);
  • 在Unity引擎中,最多只存在0~31共32个图层,图层layerMask是一个32位整数,因此在向函数传参时,对层数的选择要使用位运算传入。

4.layerMask的传参

用位运算操作可以快速创建或修改指定图层的 LayerMask,以下是一些示例:

1. 创建只包含第 0 层的 LayerMask:
int layerMask = 1 << 0;

其中 << 是左移运算符,表示将二进制数向左移动指定的位数。在这个例子中,将数字 1 向左移动 0 位,得到的结果是 00000001,即十进制数 1。因此,第 0 层的 LayerMask 值为 1。


2. 创建只包含第 1 层和第 2 层的 LayerMask:
int layerMask = (1 << 1) | (1 << 2);

这里使用了按位或运算符 |,将两个数字的对应的二进制位进行或运算。在这个例子中,将数字 1 分别向左移动 1 位和 2 位,得到的结果分别是 00000010 和 00000100。然后将这两个数进行按位或运算,得到的结果是 00000110,即十进制数 6。因此,第 1 层和第 2 层的 LayerMask 值为 6。


3. 将第 3 层添加到 LayerMask 中:
layerMask = layerMask | (1 << 3);

这里使用了按位或运算符 |,将原来的 LayerMask 值与数字 1 左移 3 位的结果进行或运算。在这个例子中,如果原来的 LayerMask 值为 6(即第 1 层和第 2 层),左移 3 位的结果是 00001000。然后将这个数与 6 进行按位或运算,得到的结果是 00001110,即十进制数 14。因此,第 1 层、第 2 层和第 3 层的 LayerMask 值为 14。


4. 将第 2 层从 LayerMask 中移除:
layerMask = layerMask & ~(1 << 2);

这里使用了按位与运算符 & 和按位取反运算符 ~,将原来的 LayerMask 值与数字 1 左移 2 位的按位取反的结果进行按位与运算。在这个例子中,如果原来的 LayerMask 值为 14(即第 1 层、第 2 层和第 3 层),左移 2 位的结果是 00000100。然后将这个数按位取反,得到的结果是 11111011。最后将这个数与 14 进行按位与运算,得到的结果是 00001010,即十进制数 10。因此,第 1 层和第 3 层的 LayerMask 值为 10。s

  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老师好我差点叫何同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值