美文网首页
unity3d问题集 <3> 对Physics.Ra

unity3d问题集 <3> 对Physics.Ra

作者: Moment__格调 | 来源:发表于2016-06-28 23:30 被阅读1747次

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

    首先说说射线;

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

    在API文档中Ray是一个结构体【Struct】

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

    static function Ray (origin : Vector3, direction : Vector3) : Ray 【构造】

    Origin: 射线的起点 direction:射线的方向 ;

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

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

    //用鼠标拾取物体


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

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

    刚刚接触ray的时候感觉Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);有点不理解,只是记下来这句可以从摄像机发出一条射线,

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

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

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

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


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

    因为单位不一样;

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

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

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

    下面说说Physics.Raycast()

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

    public static bool Raycast(Ray ray, RaycastHit hitInfo, float distance, int layerMask);

    public static bool Raycast(Ray ray, float distance, int layerMask);

    public static bool Raycast(Vector3 origin, Vector3 direction, float distance, int layerMask);

    public static bool Raycast(Vector3 origin, Vector3 direction, RaycastHit , float distance ,int layerMask );

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


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

    这里说一下public static bool Raycast(Ray ray, RaycastHit hitInfo, float distance, int layerMask);

    其他都差不多;

    Ray ray是射线;RaycastHit hitInfo是碰撞信息;float distance是碰撞距离;int layerMask是碰撞的层

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

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

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

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

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

    这包括哪些信息呢?如图:


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

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

    也说一下int layerMask吧。

    可以看到是int类型,我们之前申明并初始化了targetMask = LayerMask.GetMask("target");【这个方法在圣典的中文API中貌似没有】

    LayerMask.GetMask()方法就是把target层用返回一个对应的整数。


    Vector3 offset = new Vector3(15, 0, 0);//设置cube要移动的距离;

    hit.transform.position = hit.transform.position + offset;//移动cube;

    Physics.Raycast(ray, out hit, 100f, targetMask)

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

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

    相关文章

      网友评论

          本文标题:unity3d问题集 <3> 对Physics.Ra

          本文链接:https://www.haomeiwen.com/subject/jrhtjttx.html