UnityVR--组件4--Ray/Raycast/Linecast/OverlapSphere

news2024/12/23 14:50:23

目录

Ray/Raycast/Linecast//OverlapSphere简介

Ray类

Physics.Raycast方法

应用1:实现鼠标点击出射线并检测物体

应用2:实现鼠标点击拖拽物体

Physics.Linecast和Physics.OverlapSphere

应用3:进入范围时触发攻击


Ray/Raycast/Linecast//OverlapSphere简介

  射线(Ray类)在三维世界中从一个点沿一个方向发射的一条无限长的线,它的主要应用,例如:

  1. 在之前的文章unity oculus手柄射线中,使用从手柄射出的射线去点击VR中的UI按钮;

  2. 在普通3D游戏中,用鼠标或触摸的方式去拖拽、点击物体(构建一条从屏幕向物体的射线);

  3. 其他:射击中的瞄准器、从某一物体出发划出一个范围、等等……

  Raycast是物理系统中的一个方法,是用射线的形式检测在射线通过的道路上是否有碰撞体存在,就像以前做过的激光门伤害小游戏一样。同样类型的还有RaycastAll

  LinecastOverlapSphere是物理系统中的线性检测和球型检测,检测在线性或球形范围内是否有碰撞体,Linecast返回布尔值,OverlapSphere返回一个数组。

Ray类

  射线的两个重要参数就是起点(origin)和方向(direction)。Ray类的带参构造是public Ray(Vector3 origin, Vector3 direction)  ,也就是我们在创建一条射线时需要传起点和方向两个参数。另外,这个类中只有一个方法GetPoint(),用于返回一个射线上的点。方法定义如下:

public Ray(Vector3 origin, Vector3 direction)
        {
            m_Origin = origin;
            m_Direction = direction.normalized;
        }

public Vector3 GetPoint(float distance)
        {
            return m_Origin + m_Direction * distance;
        }

Physics.Raycast方法

  作用:在场景中发射一条射线,检测其是否与碰撞器碰撞。

  定义:(居然有15个重载)语法如下

public static bool Raycast(Ray ray)

public static bool Raycast(Vector3 origin, Vector3 direction)

public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance)

//激光门中用过:
public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance, int layerMask)

  重要参数说明:

参数作用
origin射线起点坐标(世界),Vector3
direction射线方向,Vector3
distance射线长度,float
layermask选定的检测层(其他层不检测),int
hitInfo检测到的第一个对象信息,RaycastHit类

  其中的hitInfo参数是RaycastHit类,用于存储被检测到的第一个对象的信息,包括:transform、rigidbody、collider、distance(从射线起点到与碰撞对象的交点的距离 )、point(交点的坐标)、normal(射线入平面的法向量)

Physics.Line

应用1:实现鼠标点击出射线并检测物体

  在应用中,我们经常会有用鼠标或者手柄去点击并拾取物体的需求,那就需要从屏幕(也就是Camera)或者手柄的位置发出一条射线到物体。下面就设置了捕捉鼠标左键的点击,并从主camera发射一条射线,方向是鼠标点击的位置,再用RaycastHit检测是否射到了敌人(敌人加入Enemy层)。update()中的代码如下:

Update()
{
  if(Input.GetMouseButtonDown(0))
  {//如果有鼠标左键的点击
     //定义一个射线ray,设置射线从主摄像机到鼠标位置
     Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition);
     Tools.DrawLine(transform, ray.origin, ray.direction, Color.white, 0.05f);//用Tools工具中的DrawLine方法将这条线画出来
     //测试Raycast
     Physics.Raycast(ray, out RaycastHit hit, 100, LayerMask.GetMask("Enemy","UI"));
     if(hit.collider != null)
     {
       Debug.LogError("打中敌人了!");
     }
  }
}

  效果如下图,可以看到每次射线点到红色敌人时,左下角都会有文字提示。

 应用2:实现鼠标点击拖拽物体

  实现过程:

  第一步:从Camera向鼠标点击方向做一条射线(和应用1一样);

  第二步:射线检测被拖拽物体;修改一下上面的Update()

private Transform clicked; //被鼠标点击的物体
void Update()
    {
        if(Input.GetMouseButtonDown(0))
        {//鼠标左键点击,产生一条射线
            //测试Ray,设置射线从主摄像机到鼠标位置
            ray=Camera.main.ScreenPointToRay(Input.mousePosition);
            Physics.Raycast(ray, out RaycastHit hit, 100, LayerMask.GetMask("object"));
            //这里检测object层
            if(hit.collider != null)
            {
                clicked = hit.transform;  //射线检测到的物体之后被鼠标拖拽
            }
        }
        if(Input.GetMouseButton(0))
        {//如果收到鼠标左键持续点击,实现拖拽物体
            if(clicked!= null)
            {
                Vector3 pos=Tools.MouseToWorld(clicked.position);//第三步实现的方法
                clicked.position=new Vector3(pos.x,clicked.position.y,pos.z);
                //物体高度(y)不变
            }
        }
        if(Input.GetMouseButtonUp(0))
        {//如果鼠标左键抬起,释放物体
            clicked= null;
        }
    }

  第三步:如果检测到鼠标左键持续点击,则将鼠标位置转化成三维空间位置赋给物体;

   *注:应用2重点是鼠标位置转换,鼠标的点击位置是一个二维的屏幕位置,需要将之转换为三维空间的位置,这是一个需要经常用到的转换,可以将这个方法放入Tools.cs工具集中。以下就是转换的代码,看似转来转去非常复杂,可以参照文章Unity Camera的ScreenToWorldpoint API的实现了解原理。

    //在Tools工具集中加入一个鼠标坐标转换的工具
    //将鼠标在屏幕上点击的二维坐标转换为空间三维坐标
    public static Vector3 MouseToWorld(Vector3 target)
    {//需要传入一个被点击物体的位置,因为鼠标的坐标原本只有XY,没有Z轴
        //将target的世界坐标转换为屏幕坐标
        Vector3 targetScreen=Camera.main.WorldToScreenPoint(target);
        //将鼠标在屏幕上的XY位置加上target的z位置,得到鼠标的屏幕位置
        Vector3 curseScreenPos=new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetScreen.z);
        //最后将鼠标屏幕位置转为世界位置
        Vector3 curseWorldPos=Camera.main.ScreenToWorldPoint(curseScreenPos);
        return curseWorldPos;
    }

效果如下:

Physics.Linecast和Physics.OverlapSphere

  这两个API都是在线性或球形范围中检测碰撞体,Linecast可以用于射击游戏,而OverlapSphere之前在小游戏坦克对战中使用过。它们的语法如下:

//线性检测
public static bool Linecast(Vector3 start, Vector3 end, out RaycastHit hitInfo)

public static bool Linecast(Vector3 start, Vector3 end, int layerMask)

//球形检测,返回一个数组,列出所有被检测到的碰撞器
public static Collider[] OverlapSphere(Vector3 position, float radius)

public static Collider[] OverlapSphere(Vector3 position, float radius, int layerMask)

应用3:进入范围时触发攻击

  简单做一个类似与以前做过的“坦克对战”效果。新建一个挂在主角Hero上的脚本OverlapSphere.cs

public class OverlapSphere : MonoBehaviour
{
    private Collider[] colliders;
    private GameObject bullet;

    void Update()
    {
        colliders=Physics.OverlapSphere(transform.position, 2, LayerMask.GetMask("Enemy"));
        //设定圆心、半径、检测层
        foreach(var collider in colliders)
        {
            bullet = Resload.Instance.LoadPrefab("Bullet");//加载子弹
            bullet.transform.position = transform.position;
            bullet.transform.LookAt(collider.transform);
        }
    }
}

 效果如下:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/562628.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

day13 网络编程Tomcat服务器

c/s架构和b/s架构的区别 c/s架构:客户端软件,直观,体验好,界面美观,安全性高 b/s架构:浏览器–>服务器,可移植性好,开发和维护性好 网络访问的三要素:ip,端口,协议 udp协议和tcp协议的区别 udp协议:只管发送,不管发送到哪里,是否能不能接收,一对多,无连接通信协议 ​ …

蓝桥:前端开发笔面必刷题——Day3 数组(三)

文章目录 📋前言🎯两数之和 II📚题目内容✅解答 🎯移除元素📚题目内容✅解答 🎯有序数组的平方📚题目内容✅解答 🎯三数之和📚题目内容✅解答 📝最后 &#x…

混沌演练实践(二)-支付加挂链路演练 | 京东云技术团队

1. 背景 当前微服务架构下,各个服务间依赖高,调用关系复杂,业务场景很少可以通过一个系统来实现,常见的业务场景实现基本涉及多个上下游系统,要保证整体链路的稳定性,需要尽量减少系统之间的耦合性&#x…

Elasticsearch与Clickhouse数据存储对比 | 京东云技术团队

1 背景 京喜达技术部在社区团购场景下采用JDQFlinkElasticsearch架构来打造实时数据报表。随着业务的发展Elasticsearch开始暴露出一些弊端,不适合大批量的数据查询,高频次分页导出导致宕机、存储成本较高。 Elasticsearch的查询语句维护成本较高、在聚…

CloudBase CMS的开发注意事项

引言 在进行基于云开发的微信小程序开发时为了减轻工作量打算用CloudBase CMS来减轻工作量,随后去了解并体验了CloudBase CMS的使用,总体来说还有些许问题没有解决,对减轻后台管理工作并没有起到很大的作用。 项目情景 使用CloudBase CMS来管…

Flutter 笔记 | Flutter 基础组件

Text Text 用于显示简单样式文本,它包含一些控制文本显示样式的一些属性,一个简单的例子如下: Text("Hello world",textAlign: TextAlign.left, );Text("Hello world! Im Jack. "*4,maxLines: 1,overflow: TextOverflo…

HACKABLE: III

文章目录 HACKABLE: III实战演练一、前期准备1、相关信息 二、信息收集1、端口扫描2、访问网站3、查看网站源码4、扫描目录5、访问网址6、查看并下载7、访问网站8、查看文件9、解密10、访问网站11、访问网站12、查看文件13、解密14、访问网站15、访问网站16、下载图片17、隐写1…

tcp连接阿里云linux服务器失败

原因: 自己程序bind的是127.0.0.1 应该改成 bind 阿里云的私网地址 client连接的是阿里云公网地址 参考: 阿里云服务器,客户端socket无法连接的问题 - 爱码网 排查过程记录: 1,安全组设置:有正常设置…

【C++】 模板(泛型编程、函数模板、类模板)

文章目录 模板泛型编程概念 函数模板常规使用显式指定及默认值多模板参数模板函数的声明和定义用函数模板优化冒泡排序 类模板常规使用显式指定及默认值多模板参数类中成员函数的定义和声明嵌套的类模板1.类和类型都能确定2.类和类型都不能确定3.类能确定,类型不确定…

Unity3D下如何实现跨平台低延迟的RTMP、RTSP播放

技术背景 好多开发者,希望我们能探讨下Unity平台RTMP或RTSP直播流数据播放和录制相关的模块,实际上,这块流程我们已经聊过多次,无非就是通过原生的RTMP或者RTSP模块,先从协议层拉取到数据,并解包解码&…

常用的表格检测识别方法——表格结构识别方法(上)

第三章 常用的表格检测识别方法 3.2表格结构识别方法 表格结构识别是表格区域检测之后的任务,其目标是识别出表格的布局结构、层次结构等,将表格视觉信息转换成可重建表格的结构描述信息。这些表格结构描述信息包括:单元格的具体位置、单元格…

子网掩码计算方法

子网掩码是用来划分网络的一种方式,它是一个32位的二进制数,用于将IP地址分成网络地址和主机地址两部分。子网掩码中的1表示网络地址,0表示主机地址。计算子网掩码的方式取决于需要划分的网络数量和主机数量。 以下是一些计算子网掩码的示例…

【LeetCode热题100】打卡第2天:两数相加

两数相加 ⛅前言 大家好,我是知识汲取者,欢迎来到我们的LeetCode热题100刷题专栏! 精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练…

【2】tensorflow基本概念及变量函数

目录 1 tensorflow运行机制 1.1 搭建计算图模型 计算图的概念 计算图的使用 新建计算图 1.2 在会话中执行计算图 会话的启动方式 1.3 指定计算图的运行设备 2 tensorflow数据模型 2.1 认识张量及属性 张量的类型 张量的阶 2.2 张量类型转换和形状变换 张量类型转换 张…

TwinCAT ENI 数据详解

使用倍福TwinCAT工具可以生成ENI,先对ENI的cyclic frame数据进行解释说明 需要提前了解EtherCAT报文格式,可参考下面文章 EtherCAT报文格式详解_ethercat listtype 1_EtherCat技术研究的博客-CSDN博客https://blog.csdn.net/gufuguang/article/details/…

理解HAL_UARTEx_ReceiveToIdle_IT的工作过程

先只看没错误发生, 没开DMA时候的情况 将会面临3种结局, 收满数据时候IDLE正好发生, 数据发多了, 数据已经收满时候IDLE还没发生IDLE发生了数据没收满, 首先: 接收开始 主要的动作是 1. status UART_Start_Receive_IT(huart, pData, Size); 开始中断接口 2.…

【国产虚拟仪器】基于 ZYNQ 的电能质量系统高速数据采集系统设计

随着电网中非线性负荷用户的不断增加 , 电能质量问题日益严重 。 高精度数据采集系统能够为电能质 量分析提供准确的数据支持 , 是解决电能质量问题的关键依据 。 通过对比现有高速采集系统的设计方案 , 主 控电路多以 ARM 微控制器搭配…

1992-2022年经过矫正的夜间灯光数据

夜间灯光数据是我们在各项研究中经常使用的数据!我们平时使用的夜间灯光数据主要来源于NPP/VIIRS和DMSP/OLS两种渠道,我们之前也分享过这两种来源的夜间灯光数据,包括: 2012-2021年逐年的NPP/VIIRS夜间灯光数据2012-2021年逐月的…

MySQL查询性能优化之索引覆盖、索引下推、索引潜水、索引合并

索引覆盖 什么是索引覆盖 select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖。 如何实现索引覆盖? 最常见的方法就是:将被查询的字段,建立到联合索引(如果只有一…

python---变量(2)

此处,首次使用“”对a进行设置值,也就是对a的初始化。 后续位置对a使用“”,实际上是对a赋值。 因此两行代码得到的结果显然是不同的! 变量的种类 1.整数-int-根据数据大小自动扩容 python中的变量类型不需要显示声明&#…