• Unity --- 射线检测


    从一个问题开始:我们遇到过点击游戏屏幕然后角色让我们点击的位置移动的游戏,那么问题来了,这个功能是怎么实现的呢?

    其实这个功能实现的原理就是射线检测

    1.首先我们点击的是游戏画面,而我们看到的游戏画面都是从摄像机那获取的

    在大平面 和小平面之间的所有游戏物体和我们准许拍摄的天空盒等等都会以投影的方式投到小平面上,此时在小平面上通过投影形成的画面就是我们看到的游戏画面

    现在我们想要实现一个功能:就是当我们点击游戏画面中的某处的时候会向着我们点击的位置移动

    翻译过来就是:当我们在游戏画面中点击某个位置的时候,我们要找到游戏场景中的对应点,并让我们的游戏角色在游戏场景中移动到这个点

    那么最关键的技术问题就是:当我们在游戏画面中点击某个位置的时候,我们如何找到游戏场景中的对应点呢?

    解决这个技术问题的技术就是:射线检测

    这个射线检测中的射线是从摄像机中的小平面发出的(前面有说我们看到的游戏画面就是这个小平面上的画面,当我们在游戏画面上点击的时候,其实就相当于在小平面上点击)

    要知道所有的游戏画面都是通过投影的方式投到小平面上的,也就是说这些游戏游戏也可以沿着投影路径重新投影回去

    那么我们点击画面上的某个位置的时候,在这个位置上发出一条射线,沿着投影路径射回游戏场景,然后通过这条射线我们可以检测它碰撞到的位置,碰撞到的物体

    这样我们不仅可以获取游戏角色在场景中要移动的位置,还可以获取到要移动的位置的信息

    注意这个射线不具有穿透性


    那么如何去调用射线检测这个操作呢?

    我们现在要做的是创建一个射线,并获取射线碰撞信息,和通过射线对游戏物体进行操作

    1.创建一个脚本,并把这个脚本挂载到我们要控制的游戏物体上

    2.实现鼠标在游戏画面中按下左键后,会在鼠标按下的位置生成一条射线对象

    首先判断是否是鼠标左键按下,若为是则调用下面这个生成方法:

    生成方法:Camara.main.ScreenPointToRay(这里传的参数是我们鼠标点击的位置 -- Input.mousePosition) ---- 把鼠标的位置传给方法后,方法会在对应的位置处生成一条射线,并将这条射线对象返回 --- 所以我们要创建一个射线变量来接收返回的射线对象

    (ps:由于要获取用户的键鼠输入,所以要在Updata方法中实现,保证每帧扫描,不会漏掉信息)

     3.声明一个射线碰撞信息变量,来专门承接射线的碰撞信息

    4.获取射线的碰撞信息,并赋值给射线碰撞信息变量同时进行碰撞检测

    通过physics调用Raycast这个方法,首先这个方法会将ray中的碰撞信息赋值给hit -- 这个功能是靠out关键字实现的,实现原理等以后补了C#就知道了

    然后这个方法会对hit中的碰撞信息进行判断,如果射线发生了碰撞,返回true,否则返回fasle

    (我们要创建一个bool变量来接收返回值)

    5.将bool变量接收的返回值作为判断依据,如果为ture则进行某些操作,如果为false则进行某些操作

    6.上面这种射线检测是射线单检测,射线一旦碰撞一次射线就会停下来,不再继续发射

    我们也可以进行射线多检测:

     通过Physics调用RaycastAll方法,这个方法的返回值是一个射线碰撞信息变量数组,所以我们要创建一个射线碰撞信息变量数组来接收返回值 --- 射线每碰撞一次就会返回一个射线碰撞信息对象

    然后这个方法的参数中的第一个是我们发出的射线,第二个是射线发出的长度(此时其实就是线段,然后这个参数可写也可不写,不写的时候就是射线),第三个参数是规定能够进行射线碰撞检测的图层(上图中规定的是第10层,然后这个参数可写可不写,不写的话默认检测所有图层)

  • 相关阅读:
    罗马数字转整数
    Improved Baselines with Momentum Contrastive Learning
    Linux中setfacl命令详解
    全套完整版实战型Java云HIS系统源码
    【架构设计】CAP理论、BASE理论
    python常用数据结构-元组
    【符号链接】【bash】遍历目录下的每个子项目
    QCC Tx 发射器(source)通话(麦克风输入)切换
    HTTP 基础 (基于 HTTP 的系统的组件、客户端:用户代理、网络服务器)
    VBA -[知识点]: 字典
  • 原文地址:https://blog.csdn.net/qq_51947882/article/details/126521368