草庐IT

Unity --- 射线检测

Metallic Cat 2023-07-09 原文

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

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

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层,然后这个参数可写可不写,不写的话默认检测所有图层)

有关Unity --- 射线检测的更多相关文章

  1. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  2. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  3. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  4. unity---接入Admob - 2

    目录1.AdmobSDK下载地址2.将下载好的unityPackagesdk导入到unity里​编辑 3.解析依赖到项目中

  5. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  6. ruby - 检测由 RSpec、Ruby 运行的代码 - 2

    我想知道我的代码是否在rspec下运行。这可能吗?原因是我正在加载一些错误记录器,这些记录器在测试期间会被故意错误(expect{x}.toraise_error)弄得乱七八糟。我查看了我的ENV变量,没有(明显的)测试环境变量的迹象。 最佳答案 在spec_helper.rb的开头添加:ENV['RACK_ENV']='test'现在您可以在代码中检查RACK_ENV是否经过测试。 关于ruby-检测由RSpec、Ruby运行的代码,我们在StackOverflow上找到一个类似的问题

  7. ruby - 使用 Ruby Daemons gem 检测停止 - 2

    我正在使用rubydaemongem。想知道如何向停止操作添加一些额外的步骤?希望我能检测到停止被调用,并向其添加一些额外的代码。任何人都知道我如何才能做到这一点? 最佳答案 查看守护程序gem代码,它似乎没有用于此目的的明显扩展点。但是,我想知道(在守护进程中)您是否可以捕获守护进程在发生“停止”时发送的KILL/TERM信号...?trap("TERM")do#executeyourextracodehereend或者你可以安装一个at_exit钩子(Hook):-at_exitdo#executeyourextracodehe

  8. ruby - Ruby 脚本如何检测到它正在 irb 中运行? - 2

    我有一个定义类的Ruby脚本。我希望脚本执行语句BoolParser.generate:file_base=>'bool_parser'仅当脚本作为可执行文件被调用时,而不是当它被irbrequire(或通过-r在命令行上传递)时。我可以用什么来包装上面的语句,以防止它在我的Ruby文件加载时执行? 最佳答案 条件$0==__FILE__...!/usr/bin/ruby1.8classBoolParserdefself.generate(args)p['BoolParser.generate',args]endendif$0==_

  9. Ruby 无法检测字符串中的换行符 - 2

    我有以下字符串,我想检测那里的换行符。但是Ruby的字符串方法include?检测不到它。我正在运行Ruby1.9.2p290。我哪里出错了?"/'ædres/\nYour".include?('\n')=>false 最佳答案 \n需要在双引号内,否则无法转义。>>"\n".include?'\n'=>false>>"\n".include?"\n"=>true 关于Ruby无法检测字符串中的换行符,我们在StackOverflow上找到一个类似的问题: h

  10. Unity Shader 学习笔记(5)Shader变体、Shader属性定义技巧、自定义材质面板 - 2

    写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c

随机推荐