前言
在学习Vector3和Transform之前需要先了解一下Unity坐标系:
在Unity中有很多坐标系,诸如世界坐标系、局部坐标系、屏幕坐标系、视口坐标系等等,这些坐标系往往会给我带来很大的困扰,但又缺一不可。比如当你需要获取鼠标在世界坐标的位置时,你就需要明白什么是世界坐标和屏幕坐标,以及两者如何转换。
一、坐标系
参考视频:Unity的各种坐标系
1、分类
1)世界坐标
当你从Unity中新建了一个物体对象,它所具有的Transform参数所采用的就是世界坐标系,该坐标系分为左手坐标系和右手坐标系,其中如图所示。其中左手坐标系就是Unity中的世界坐标系,也就是Z轴为正,X轴为右,Y轴为上,而右手坐标系在数学中更加常用。
Unity中一个物体的坐标信息,通过Transform.position来存储,它是一个Vector3变量,是一个三维向量,存储了XYZ的信息。
在Unity中,可通过Transform.forward来表示正方向,Vector3.forward也可以表示正方向,这两者的区别在于:
Vector3.forward的值永远是(0,0,1),而transform.forward的值则是根据当前物体的自身坐标系Z轴,不一定等于(0,0,1) 怎么理解呢,举个例子:
首先一个物体的transform.position,一定是该物体在世界坐标的位置,相应的transform.localPosition才是该物体的局部坐标,那么transform += Vector3.forward时,就等于在向世界坐标的Z轴前进,而transform += transform.forward时,则等于再向局部坐标的Z轴前进。
2)屏幕坐标系
屏幕坐标系就是把屏幕看作一个坐标系,从左下角开始计算,也就是(0,0),而右上角则是(Screen.widht,Screen.height),所以又叫做像素坐标系。这里不管是视口坐标还是屏幕坐标,其z值还是有的,是表示深度的。
3)视口坐标系
该坐标系计算方式和屏幕坐标系类似,只不过把其参数标准化了,更加适用于比例计算。
左下角为(0,0) 右上角为(1,1)。这里不管是视口坐标还是屏幕坐标,其z值还是有的,是表示深度的。
4)GUI坐标系
该坐标是从左上角开始计算的,左上角(0,0),右下角为(Screen.width,Screen.height)。
2、坐标系的相互转换
1)世界坐标和屏幕坐标的相互转换
//屏幕坐标转世界坐标
Camera.ScreenToWorldPoint(Vector3 Pos);
//世界坐标转屏幕坐标
Camera.WorldToScreenPoint(Vector3 Pos);
这些转换一般应用于想要通过鼠标来操作世界物体,比如物体跟随鼠标移动…
2)世界坐标和视口坐标的相互转换
//世界坐标转视口坐标
Camera.WorldToViewportPoint(Vector3 Pos)
//视口坐标转世界坐标
Camera.ViewportToWorldPoint(Vector3 Pos);
这个原理和上一个差不多,因为屏幕和视口是可以相互转换的,所以把上面的转换函数换成下面的也是成立的,前提是最后用视口转世界坐标时,要把鼠标位置屏幕坐标先转成视口再使用。
3)屏幕坐标和视口坐标的相互转换
//屏幕坐标转视口坐标
Camera.ScreenToViewportPoint(Vector3 Pos)
//视口坐标转屏幕坐标
Camera.ViewportToScreenPoint(Vector3 Pos);
4)世界坐标和局部坐标的相互转换
//世界坐标转局部坐标
transform.InverseTransformPoint(Vector3 Pos);
transform.worldToLocalMatrix
//局部坐标转世界坐标
transform.TransformPoint(Vector3 Pos);
transform.localToworldMatrix
3、坐标系混淆
大家在使用坐标系的时候,可能听过很多很多别称,很容易对一些较为生僻的叫法产生疑惑,这里给大家梳理一下。
- 世界坐标、全局坐标、左手坐标、绝对坐标
- 局部坐标、自身坐标、物体坐标、本地坐标、相对坐标
- 屏幕坐标、像素坐标
- 视口坐标、视窗坐标
- GUI坐标、UI坐标
二、Vector3基础
1、Vector3主要是用来表示三维坐标系中的一个点或者一个向量
申明:
Vector3 v = new Vector3();
v.x = 10;
v.y = 10;
v.z = 10;
只传xy,z默认为0
Vector3 v = new Vector3(10, 10);
2、基本运算及部分常用方法
Vector3 v1 = new Vector3(1, 1, 1);
Vector3 v12 = new Vector3(2, 2, 2,);
print(v1 + v12);
print(v1 - v12);
print(v1 * v12);
print(v1 / v12);
//常用
print(Vector3.zero);//000
print(Vector3.right);//100
print(Vector3.left);//-100
//常用的方法
print(Vector3.Distance(v1, v12));
三、transform位置
1、两种相对位置
分为相对世界坐标系的position位置和相对父对象的localPosition
//相对世界坐标
print(this.transform.position);
//相对父对象坐标
print(this.transform.localPosition);
如果你想以面板坐标为准来进行位置设置,那一定是通过localPosition来进行设置的。
当父对象在世界坐标系原点,或者对象没有父对象时,这二者是一样的。
2、修改位置
1)直接赋值
this.transform.position = new Vector3(99, this.transform.position.y, this.transform.position.z);
2)先取出来再赋值
虽然不能直接修改transform的xyz但是Vector3是可以直接修改xyz的,所以可以先取出来修改Vector3再重新赋值
Vector3 vPos = this.transform.localPosition;
vPos.x = 99;
this.transform.localPosition = vPos;
3、获取位置
//面朝向
print(this.transform.forward);
//头顶
print(this.transform.up);
//右手边
print(this.transform.right);