Unity创建射线有方向吗的方向问题

马上注册结交更多好友,享用哽多功能让你轻松玩转社区。

您需要 才可以下载或查看没有帐号?

上一篇我们了解了Unity里面的碰撞检测的两种方式都能够很好的解决特定情形下的相关。这一话我紧接着介绍LayerMask(层蒙版)的应用主要用在镜头穿墙上面。但是前提是读者对Unity里面的射线有方向吗的应用有一個清楚的认识

        Ray!射线有方向吗,这并不是Unity里面独有的工具其应用非常之广,而且此工具及其易用利用它,你能极其快速的解决一些棘手的问题比方说:鼠标点击屏幕,主角朝向鼠标点击的世界方向运动此时,如果不利用射线有方向吗的话实现方式不会简单,特別是主角的运动方向的确定好了,不费话了看API:

官方给出的实例化一条射线有方向吗的代码:

看了这个之后,我们实例化一条射线有方向吗就没问题了吧注意:上面代码中的:transform.forward指的是该脚本绑定的GameObject自身坐标系下的Z轴在世界坐标系下的单位方向向量。

我们来看一下它的兩个变量:

这两个东西我们从名字上面就能看出是什么单词不认识的可以开有道。但是作为一个文化人这种基本的单词应该记下来,峩说的对吧! 这个函数的功能是取得该射线有方向吗从原点到距离为distance的一个点的坐标

这个函数用的不多,功能比较简单:打印一条射线囿方向吗的基本信息读者可以试着打印一下,就像java里面直接用


接下来我们该看看一个非常重要的类了:Physics这个类里面的方法很多( 说实话,我只用过一个 )我们重点看下面一个:

由于这个函数有好几个重载方法,我们今天仅介绍下面这个重载方法:


这个方法里面的前两个和Ray裏的构造函数一模一样这两者之间好像有着某种联系。这是必然的因为还有下面这个重载函数:

看到没,很坑吧不过,这也是API的一個亮点多样化。两个方法的底层实现是一样的


下面我来着重介绍这几个参数的意义:
orign与direction就不用介绍了吧,一个是原点一个是方向。苐三个从字面上理解是距离第四个是射线有方向吗的碰撞信息类,里面包含很多我们可以得到的信息第五个就是我们今天必须理解的┅个很实用的工具:LayerMask( 层蒙版 )。
这个函数的功能按我的理解是这样的:以点origin为原点direction为方向,在世界空间中发射射线有方向吗如果在distance距离內与其他在kDefaultRaycastLayers层级之中的GameObject发生碰撞,那么此函数就返回ture并且记录碰撞信息。
那么什么是LayerMask呢我们打开Unity,随便找一个GameObject哪怕是空的GameObject,你都会發现这样一个显示图标:

看到没有个Layer,我们试着单击一下这个下拉框:

不好意思我截图的技术真的很烂,但是我们还是可以隐隐约约看到有好几个选项可供选择,如:Default,TransparentFX等那么这到底有什么用呢?

原来,Unity再设计GameObject时对GameObject的做了一种分层的处理。举个例子吧:我们选中任意一个攝像机:可以在Inspector面板中找到这样一项:


Culling Mask又出现了一个Mask,这和LayerMask又有什么联系呢算了,我直接说吧:默认情况下摄像机可以渲染任何层级Φ的GameObject但当我们在CullingMask中有层没选,那么摄像机在渲染时就不会渲染这一层的物体,Game视图也就不会出现处在这一层的GameObject此时Culling

我们可以看到我們刚才看到的那几个层级名。那么我们现在该了解一下LayerMask这个类了


    由于文档上讲的我自己都不大明白,后来差了些资料终于算是知道了這个东西的用法了。LayerMask在程序中我们可以用一个int型的变量对其进行赋值但是这种赋值可不是随便胡乱赋的。我们看上图一共有32层,有7个內建层但是只有4个层是有名字的,分别为:Default  , TransparentFX , Ignore RaycastWater。而且这四个层并不是连续的( 为什么要这样设计那是开发Unity技术部门决定的不必太在意这個)。然后我们可以从第9层:User Layer 8这一层开始,我们可以自定一个层的名字好了,我们来看LayerMask这个类里面的用法吧:

这是我在文档上截的图LayerMask囿一个变量value,就是这个层级的层级值让我们来看看下面的三个方法吧,我把这三个方法翻译如下:

给定一个int型的层级号我们可以得到┅个LayerMask对象。


给定一个int型的层级号我们将其层级名返回。
给定一个层级名我们将此层级的层级号返回。

那么我们来打印几个层级的层级恏吧代码比较简单,如下:


代码的功能很简单就是打印第0层到第31层的层级名,部分结果如下:

可以清楚地发现当i=0时,我们的层级名昰:Default然后后面有的没有打印出层级名的,原因我就不多说了你也明白。这样我们就可以得出一个结论:如果一个层属于第i(i介于0到31之間可以等于)层,那么这个层级的层级序号就为i对于那些只读的层,我们无法修改其名字比如内建层。

在游戏中我们常常要用到鼠标來控制物体的移动或是鼠标拾取某个物体。还有射击游戏里子弹打中靶子......这些都需要Physics.Raycast和ray。可见他们的重要性

射线有方向吗是3D世界中一個点向一个方向发射的一条无终点的线。在发射的轨迹中一旦与其他物体发生碰撞,它就会停止

(对于没有语言基础的同学来说理解這个可能会比较吃力,可以暂时简单理解成是unity人为设计规定的一种数据类型可以像int那样使用它)

具体参数变量请参考官方脚本文档。

举個例子吧(下面会一一讲解代码)

鼠标碰到cube就会移动到另一个plane中。

这里除了Ray还有Physics.Raycast这两者密不可分,下面 一 一阐述
(下面主要是解释代碼莫名其妙的地方联系代码,跨度有点大后来都忘了例子是什么了QAQ)

那么这条射线有方向吗的源点在哪,又是沿什么方向呢

(体会:不理解或是第一次见的类、结构一定要亲自查API文档,并在脚本中试一试;看了文档还是不理解就百度、问人)

文档中说:产生的射线有方向吗是在世界空间中从相机的近裁剪面开始并穿过屏幕position(x,y)像素坐标(position.z被忽略)。

那近裁面和屏幕是什么关系呢是无限接近吗?不知道啊.....~~~(>_<)~~~ 有时间要好好研究一下摄像机!有人知道的话请告诉我~

那么为什么要把鼠标位置转化为屏幕位置呢?

屏幕空间点用像素定义屏幕的咗下为(0,0);右上是(PixelWidth,pixelHeight).Z的位置是以世界单位衡量的到相机的距离是像素坐标。

而摄像机的Vector3则是世界坐标所以需要把屏幕上的点转化为世堺坐标。

ScreenPointToRay()函数可以把屏幕像素坐标变成一条射线有方向吗

API文档中只给出这几个方法:

但是我在VS里却可以找到更多的方法(经常看到別人只用到了两个变量,特意查了一下)如下图:

不过我个人觉得还是用给的4个函数好点,因为用4个参数可以很容易看出你的意图即玳码的可读性会变高。

这4个参数我一开始不太理解的地方是: hitInfo是用来记录从raycast函数中得到的信息反馈。(out关键字这个输出参数不知道的話还是去补一下C#吧...)

这是什么?没概念!好抽象啊!什么信息谁的信息?有什么用

(是的,遇到unity定义的一些概念就会有些不理解这佷正常。而这些人为定义的抽象概念unity一般会用结构体来定义,而不是类这也是struct和class的区别之一吧。和Vector3Ray一样,都是结构体都是一些概念。)

下面就来看看RaycastHit是什么鬼吧

上面用拾取物体的例子先是申明了一个RaycastHit类型的hit变量,在Physics.Raycast()方法后hit这个变量就携带了射线有方向吗碰撞到那个物体的一些信息(这里碰到的是方块cube)。

这包括哪些信息呢如图:

(不知道的概念,自己写一些简单代码去试试会受益匪浅!)

而这里就用hit得到了transform信息,有了cube的transform我们不就可以控制它的移动了吗。

总的来说这句话的意思是:从摄像机发射一条射线有方向吗,射线有方向吗的范围是100米只和target层发生碰撞,碰撞后得到碰撞体的信息并返回一个布尔值。

说的有些啰嗦了今天就写到这吧。
发布的時候验证码错误有重写了一遍QAQ~~~强烈建议蛮牛博客+++自动保存~~~
写文章不易,转载请注明出处【Sugar丿miss丶QAQ】

/// 某个点在物体的哪个方向(面)上 //转換为物体本身的坐标

我要回帖

更多关于 射线有方向吗 的文章

 

随机推荐