[unity3D基础篇01]空间坐标系和物体移动的较深入分析

来源:互联网 发布:中关村软件破解 编辑:程序博客网 时间:2024/06/11 18:02

n年前建的号一直没有用过,这次趁着学习的机会利用一下,随时总结下学习到的东西。就当自娱自乐也可以

学习unity3d大约三个月了,感觉自己还是入门级水平,继续加油吧。

这次是第一篇,主题是空间坐标系和物体移动。那我先来看下unity3d里面的空间坐标系,一共有四种:

1.World Space(世界坐标):我们在场景中添加物体(如:Cube),他们都是以世界坐标显示在场景中的。transform.position可以获得该位置坐标。

2.Screen Space(屏幕坐标):以像素来定义的,以屏幕的左下角为(0,0)点,右上角为(Screen.width,Screen.height),Z的位置是以相机的世界单位来衡量的。注:鼠标位置坐标属于屏幕坐标,Input.mousePosition可以获得该位置坐标,手指触摸屏幕也为屏幕坐标,Input.GetTouch(0).position可以获得单个手指触摸屏幕坐标。

例如:

// 从当前鼠标坐标创建一条射线

var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);

if (Physics.Raycast (ray)) {// 碰撞检测并出发事件}

3 ViewPort Space(视口坐标)

4 绘制GUI界面的坐标系:这个坐标系与屏幕坐标系相似,不同的是该坐标系以屏幕的左上角为(0,0)点,右下角为(Screen.width,Screen.height)

下面代码来自摘抄:

public classPosition :MonoBehaviour

{

     //场景的相机,拖放进来         

    publicCameracamera;

    //场景的物体        

    privateGameObjectobj; 

    void Start()

    { 

        //初始化        

        obj =GameObject.Find("Plane");

    }

    void Update()

    {

        if(Input.GetMouseButtonDown(0))

        {

            print("世界坐标" +obj.transform.position);

            print("屏幕坐标" +Input.mousePosition);

            print("Plane 世界坐标→屏幕坐标" +camera.WorldToScreenPoint(obj.transform.position)); 

            print("鼠标屏幕坐标→视口坐标" +camera.ScreenToViewportPoint(Input.mousePosition)); 

            print("Plane 世界坐标→视口坐标" +camera.WorldToViewportPoint(obj.transform.position));

        }

    } 

}

下面是这次的重点,在自身坐标系与世界坐标系中的物体的移动:

首先实现物体的移动需要使用Transform类。这个类的属性和方法不在此详述。

重点:Unity3d vector3.forward和transform.forward的区别!

在unity3d中有2个forward,一个是vector3.forward和transform.forward

这两个forward其实完全不一样。他们之间的区别主要体现在在自身坐标系与世界坐标系的反映上。

总结一下 vector3.forward和transform.forward的区别:

1.vector3.forward的值永远等于(0,0,1)。

2.transform.forward的值则等于当前物体的自身坐标系z轴在世界坐标上指向,因此不一定等于(0,0,1),但是其magnitude长度是1。

想要让物体向前移动,在transform.Translate()上和直接修改transform.position

   transform.Translate(Vector3.forward,Space.self) 

   = transform.position += transform.forward (transform.position 本身就是世界坐标)

如下面这个我在测试时候的截图。monster在世界坐标系中(右上角)的移动方向(Z轴)是向屏幕里面,

而它的自身坐标系中Z轴是移动的正方向。所以如果要让它向前方移动需要在世界坐标中使用它的自身坐标

的方向。如果我们使用了世界坐标的话,(即transform.position += Vector3.forward)monster会朝着世界坐标的前方,也就是屏幕里面移动,这样就不对了。




下面还是来总结下吧。参考了这篇博客:http://blog.csdn.net/kaluluosi111/article/details/17206655


1.让物体在世界坐标的z轴前进。(Vector3.forward在世界坐标系和自身坐标系都是(0,0,1)

  transform.position+= Vector3.forward

  或 transform.Translate(Vector3.forward, Space.world) 

2.让物体自身坐标系的z轴前进。

  transform.position+= transform.forward

  或 transform.Translate(Vector3.forward,Space.self) 

  或 transform.Translate(transform.forward,Space.world)


当然,实现物体的移动还有个更好的方法就是使用刚体,我也是今天才看到。。不过只适合3d的物体

首先给需要移动的物体添加刚体属性。然后使用它的rigidbody.velocity这个方法来实现。即给物体一个初速度:

this.GetComponent<Rigidbody>().velocity = transform.forward * speed;

this.GetComponent<Rigidbody>().velocity =new Vector3(1,0,0)* speed; 

只写在Start () 里面即可。如果使用transform需要写在Update()中。

下面给出一个物体移动并播放动画然后达到目标后停止的代码参考:

void Update ()  

 {  

      Move ();  

      if (m_bMoving) {  

            animation.Play ("walk");  

            rigidbody.velocity = transform.forward * heroXSpeed*1.1f;   

           if (Vector3.Distance (transform.position, m_targetPos) < 0.1f) {  

                //hero的位置与目的地点距离只有0.1时 停止动画 停止移动 进入等待  

                rigidbody.velocity = Vector3.zero;   

                m_bMoving = false;  

    animation.Play ("wait");  

           }  

       }  

   }  

   void Move(){  

       if (Input.GetKey (KeyCode.D)) {  

            //记录下目标点  

            m_targetPos =new Vector3(transform.localPosition.x+1,

            transform.localPosition.y,transform.localPosition.z);  

            transform.LookAt (m_targetPos);  

            //改变移动State  

            m_bMoving = true;  

        }  

   }  

这次先总结到这里吧。有写错的地方欢迎随时指正!下一篇还不知道何时有时间写。。


0 0