美文网首页Unity
Unity_新手必懂知识点|你可能并不完全认识的transfor

Unity_新手必懂知识点|你可能并不完全认识的transfor

作者: riki_tree | 来源:发表于2019-05-05 14:23 被阅读0次

    基础知识:

    Transform作为Unity中游戏对象最为重要的组件,“位置”作为Transfrom组件的一个属性,具有同等重要的地位。

    Transform组件下有两个“位置”属性:

    position:指的是游戏对象中心点在世界空间的位置(世界空间就是Unity最大的空间,可以创建一个无任何父节点的空对象,其position,rotation分量都是0,scale分量都是1,那么可以认为世界空间就是以此物体中心点为原点,物体的朝向为z轴,右方向为x轴,上方向为y轴,即物体的transform.forward为z轴,transform.right为x轴,transform.up为y轴,如图中的SuperParent物体)。


    SuperParent1.jpg

    localPosition:指的是游戏对象中心点在父类空间的位置(属性面板上显示的值就是这个值)。

    父类空间的构建与其position,rotation,scale有关,但此处只讨论position,因此可以认为父类物体不旋转,没有缩放的情况。那么此时父类空间是以父类中心点为原点,x,y,z与世界空间x,y,z轴同方向。

    如果游戏对象没有父类,那么此物体的父类空间就是世界空间,此时position和localPosition值是相同的。可以想象为,其父类就是文章上面的SuperParent物体。

    UGUI下所有的UI空间都具有RectTransform组件,此组件继承自Transform组件,其内部的position和localPosition属性也继承自Transform。他多出来的位置属性是:

    anchoredPosition3D:指的是物体中心点Pivot相对于锚点Anchor的位置(UI属性面板上显示的就是这个值,即PosX,PosY,PosZ)。

    注意:

    1、 这里指的是锚点,尽管锚点是附加在父类上的,但其并不是父类空间,父类空间指的是以其中心点为原点,而此处指的是以锚点为原点。

    2、 RectTransform提供了我们足够的自由去更改UI的锚点位置和中心点的位置。但是万变不离其宗:anchoredPosition3D核心概念没变:中心点相对锚点的位置。

    3、 anchoredPosition是anchoredPosition3D属性去除了z轴之后的值。

    扩展知识:

    尽管上述概念都是大家耳熟能详的东西,有关的博文一搜一大堆,我为什么要再总结一篇大家都知道的东西呢?因为看似简单的东西,可以做出复杂的系统,看似复杂的东西,都是由简单的东西堆砌出来的。

    重点来了:位置脱离了空间系统毫无意义。人尽皆知啊。接下来请牢记:位置计算一定要统一空间。

    Unity中,游戏物体除了有本地位置,世界空间位置,还有相对摄像机的位置(视角空间位置),屏幕空间位置。其中的转换详情计算机图形学,以后我也会总结有关图形学的知识。

    实战:

    最后用一个例子介绍一下这些位置的用途。

    王者荣耀英雄展示界面。一边为英雄模型,一边为UI显示英雄技能等信息,是怎么样做到的模型跟正好显示在了规定的地方。如图:


    Hero.jpg

    两个接口(Camera组件下):

        public  Vector3 WorldToScreenPoint(Vector3 position);
        //输入物体世界空间坐标得到物体当前摄像机下屏幕空间坐标位置
        public Vector3 ScreenToWorldPoint(Vector3 position);
        //输入物体当前摄像机下屏幕空间坐标得到物体世界空间坐标位置
    

    注意:

    1、屏幕空间坐标依赖于摄像机。同一物体,在不同摄像机下,其得到的屏幕坐标是不同的。不懂的话,可以了解一下图形学坐标转换。

    2、屏幕空间坐标是三维的。其x,y轴是指显示在屏幕上的位置,z轴具有特殊意义——物体的深度值(与物体距离摄像机的远近有关)。

    Camera组件下有很对关于空间位置的计算。有兴趣的话,可以研究研究。

    首先我们需要两个摄像机:一个UI摄像机显示UI,一个模型摄像机显示模型。

    具体思路:由UI位置计算其屏幕坐标位置,再由屏幕坐标位置计算模型世界空间位置。

    场景:一个button,button下有一个位置标识,通过我点击button,会在该位置标识上生成一个小球(这个button同时充当了模型展台,小球就是宫本。太low了,哈哈),game场景如下:


    Scene.png

    代码如下:

        public GameObject prefab;           //小球预制件
        public Camera uiCamera;             //UI摄像机
        public Camera modelCamera;          //模型摄像机
        public GameObject posTag;           //需要把模型放置的位置
        public int z = 5;                   //修改屏幕坐标的Z轴
        public void ClickButton()
        {
            //初始化物体
            GameObject go = GameObject.Instantiate(prefab);
            Vector3 showPos = posTag.transform.position;
            //获取展示位置的屏幕空间坐标
            Vector3 screenPos = uiCamera.WorldToScreenPoint(showPos);
            //设置屏幕坐标的z轴。z轴代表物体的深度值,与距离摄像机的远近有关。
            //可以调一下大小感受一下
            screenPos.z = z;
            //获取模型摄像机下得到同一屏幕空间坐标的世界空间坐标
            Vector3 modelPos = modelCamera.ScreenToWorldPoint(screenPos);
            go.transform.position = modelPos;
        }
    

    效果展示:


    position.gif

    位置不对啊?其实是因为所有的坐标都是以中心点为基础的。小球的中心点在圆心,所以小球的中心点是与标志物重合的。在游戏中,美术提交的模型中心点基本都会设置在人物脚上,所以就不会出现这个情况。

    小结:

    知识点:位置概念不能脱离空间。位置计算一定要统一空间。

    相关文章

      网友评论

        本文标题:Unity_新手必懂知识点|你可能并不完全认识的transfor

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