Unity3d八 Unity使用的坐标系

unity recttransform 和transform有什么区别http://www.jianshu.com/p/dbefa746e50d
前言
需要在代码中调整改变UI控件的属性,比如位置、大小等,然而在NGUI里面,控制UI控件的位置等属性的是RectTransform这个组件,
这个组件继承自Transform组件,却增加许多自己的特性,在不了解这些特性的情况下鲁莽的去使用它,会导致出现很多匪夷所思的问题,而且使用起来也不够得心应手,
于是决定研究一下RectTransform到底是如何工作的
你将学得到什么?
什么是Pivot
什么是Anchor
如何结合使用Pivot和Anchor来调整UI
了解RectTransform其他属性的作用
一、Pivot属性详解
首先为了让大家更好的理解内容,我在Unity中创建了两个UI控件,一个Plane控件,作为父对象,一个Image控件,最为子对象,如下图:
然后我们选中红框,来看看它的RectTransform组件的属性,如下图:
你会看到有一堆的数据,那么这些数据是如何最终决定UI在屏幕中的位置和大小的呢?我们首先来看第一个重要的属性Pivot,因为它理解RectTransform这套UI布局方案的第一个关键
Pivot我们可以暂且称它为中心轴(这个翻译不太准确,但为了便于理解,先这么叫着),它是一个X,Y值范围是0到1的点,这个点的会在Anchor(锚点)计算位置的时候会使用到,下面用一张图来解释Pivot点的位置
设置Pivot的坐标系如上图,(0,0)表示红框物体的左下角的点,(1,1)表示红框物体的右上角的点
二、Anchor属性详解
关于Anchor锚点可能接触过UI的朋友都了解一些,但是Unity中Anchor应该称它为锚框更为合理,因为它是由两个锚点(Min,Max)组成的一个矩形,当然也可以组成一个点(两个点重合)
三、Pivot和Anchor的结合
在了解了Pivot和Anchor分别是什么后,我们就来看看Unity是如何使用这个两个东西来控制UI的布局
第1种情况:两个锚点重合时
我们先来看看两个锚点重合时的情况,这种情况是我们最常用也是最容易理解的方式
我们将Anchor锚点放在黑框的正中间,然后将Pivot中心轴放在红框的正中间,然后我们改变黑框的大小和位置,看看红框会有什么变化,如下图:
我们从上图可以看出,不管我们怎么拖动黑框,改变他大小和位置,红框的Pivot点到Anchor点的距离是始终不变的,
也就是说红框物体会参照锚点来实时调整自己的位置,使自己的Pivot点到锚点的距离始终保持一致,而且值得一提的是,在这种情况下,
红框物体的RectTransform组件中的属性是Width和Height,这个属性在后面的情况中会发生变化,大家需要注意下
总结下第1种情况的特点就是:子物体的大小不会随着父物体的大小变化而变化,但是位置会根据Pivot点到Anchor点的距离一致的原则发生对应的变化
第2种情况:两个锚点不重合时,即锚框的情况
当两个锚点(AnchorMin和AnchorMax)不重合时,两点就会确定一个矩形,这个矩形就是我们的锚框,如下图中的绿框就是我们的锚框区域
此时我们再观察一下红框物体的RectTransform属性,发现属性分别变成了Left、Top、Right、Bottom
那么这4个属性分别表示什么呢?我们看看下面的这个图
从上图我们看出,Unity以锚框的左下角为坐标系的原地(0, 0),然后红框的Left和Bottom两个数确定红框左下角的点在坐标系中的位置,原点和红框左下角的点确定一段距离
(即上图的绿色箭头),不管黑框如何变化,这段距离都保持不变
注意上图中红框左下角到黑框左下角的距离,以及红框右上角到黑框右上角的距离,他们都是不变的
三、anchoredPosition属性详解
anchoredPosition根据名字的含义,我们大概可以猜出他是根据anchor锚点得出来个一个位置属性,他本身是一个点,如果在AnchorMin和AnchorMax是重合的情况下,
anchoredPosition就是表示锚点到Pivot的位置,如下图所示:
但是如果AnchorMin和AnchorMax不重合的时候,anchoredPosition就比较复杂了,在这种情况下,Unity会根据Pivot、AnchorMin和AnchorMax计算出一个锚点,
然后在通过Pivot和锚点来得出anchoredPosition的位置,关于如何计算规则,有兴趣的朋友可以自己逆推一下


Unity3D里的各种坐标系http://blog.csdn.net/kingsea168/article/details/49611285
自从Unity4.6版本推出uGUI后,unity3d坐标系的大家庭中便增加了RectTransform这个新成员,如果你不想被各种坐标系搞得晕头转向的话,那么请随我一起来梳理下Unity3D中各种各样的坐标系!
一、Unity3D中有哪些坐标系?
Unity3D中的坐标系目前可以分为以下四类:世界坐标、屏幕坐标、视图坐标和GUI坐标。
世界坐标
世界坐标按照笛卡尔坐标系定义出来的绝对坐标系,下面的各种坐标系都建立在世界坐标的基础上。我们知道二维平面内任意一个点可以用二维坐标(x,y)来表示,
如果将这个概念延伸到三维空间内,那么三维空间内任意一个点都可以用三维坐标(x,y,z)来表示。这就是世界坐标的概念啦,坐标系通常可以分为左手坐标系和右手坐标系,
而Unity3D采用的是左手坐标系。在Unity3D中我们可以使用transform.position来获取场景中一个物体的世界坐标,
通常情况下编辑器中的Inspector窗口是以世界坐标来描述一个3D物体的位置的,除非当一个3D物体存在父物体的时候,它会以相对坐标来描述其位置。
屏幕坐标
屏幕坐标是以像素来定义的,它的范围是以左下角为(0,0),右上角为(Screen.width,Screen.height)定义的这样一个矩形。
屏幕坐标是一个3D坐标,Z轴是以相机的世界单位来衡量的。屏幕坐标和相机之间满足:Screen.width=Camera.pixelWidth和Screen.height=Camera.pixelHeight这两个条件。
例如我们将相机正对着场景中的原点(0,0,0),相机的Z轴分量为-10,按照屏幕坐标的定义,假设屏幕为800X640的大小,则此时原点转化为屏幕坐标后应该是(400,320,10)。
在Unity3D中我们可以使用WorldToScreenPoint来将一个世界坐标转换为屏幕坐标。
视口坐标
视口坐标是标准化后的屏幕坐标。标准化的概念我们可以引申到向量的标准化中,比如一个向量(x,y)将过标准化后可以得到一个单位向量(x’,y’)。
类似地,视口坐标是以0到1间的数字来表示的,它的范围是以左下角为(0,0),右上角为(1,1)定义的这样一个矩形。视口坐标是一个3D坐标,
Z轴是以相机的世界单位来衡量的。通过对比可以发现视口坐标和屏幕坐标特别的相似,所以这里大家可以对比着来学习。同样以屏幕坐标中的例子来将这里的转换,
例如我们将相机正对着场景中的原点(0,0,0),相机的Z轴分量为-10,按照屏幕坐标的定义,假设屏幕为800X640的大小,则此时原点转化为屏幕坐标后应该是(0.5,0.5,10)。
在Unity3D中我们可以使用WorldToViewportPoint来将一个世界坐标转换为视口坐标。
GUI坐标
GUI坐标是指通过OnGUI方法绘制UI时使用的坐标。这个坐标系和屏幕坐标类似,它同样是以像素来定义的,它的范围是以左上角为(0,0),
右下角为(Screen.width,Screen.height)定义的这样一个矩形,GUI坐标是一个2D坐标(绝对坐标)。因为GUI在早期的文章中曾有所设计,
属于Unity3D中较为基础的内容,此外我们知道使用绝对坐标来进行布局的话是没有办法做自适应的,所以这部分内容我们就不展开讲了,
UI自适应的一个主要观点就是不要使用绝对坐标!不要使用绝对坐标!不要使用绝对坐标!重要的事情要说三遍的嘛!这里想特别说说Unity4.6以后推出的全新UI支持:
uGUI。在uGUI的Screen Space模式下,Unity3D的编辑器以屏幕坐标来显示UI元素的位置;在World Space模式下,Unity3D的编辑器以世界坐标来显示UI元素的位置。
uGUI的坐标本质上是特殊的屏幕坐标,因为uGUI的Anchor决定了该坐标系的原点,pivot决定了元素本身坐标系的原点,
正是这两个属性让uGUI的坐标看起来显得扑朔迷离。RectTransform组件继承自Transform,所以它们的position和localPosition是等价的,都是世界坐标;
anchoredPosition是UI元素的屏幕坐标,在对UI元素进行操作的时候应该考虑使用这个坐标。


骨骼动画是一组4X3仿射矩阵的集合
4X3仿射矩阵的由来
三维空间的点矢量m+作用于m点的附加操作旋转、缩放、平移变换r=a点矢量,这个过程如何表达
点m=(m0,m1,m2)扩充后四维后为:m=(m0,m1,m2,1)
附加操作旋转、缩放、平移r=
r_3x3, 0_3x1
t_1x3, 1
其中r_3x3表示旋转、缩放操作(零化r_3x3后,r_3x3的对角线的数字表示缩放,其他位置表示旋转),t_1x3表示平移操作
m+r=(m_1x3*r_3x3+t_1x3,1)
为了简化存储r操作,r_4x4矩阵记做r_4x3(因为最后一列为(0,0,0,1)^T)
为了简化r_3x3,r_3x3=缩放矢量s_1x3+Quart_1x4


四元数http://blog.csdn.net/silangquan/article/details/39008903
旋转的表达方式有很多种,有欧拉角,旋转矩阵,轴角,四元数等
从欧拉角和轴向角到四元数
在讲四元数之前,我们先来看下简单的欧拉角和轴向角。
欧拉角
欧拉角使用最简单的x,y,z值来分别表示在x,y,z轴上的旋转角度,其取值为0-360(或者0-2pi),一般使用roll,pitch,yaw来表示这些分量的旋转值。
需要注意的是,这里的旋转是针对世界坐标系说的,这意味着第一次的旋转不会影响第二、三次的转轴。
欧拉角容易出现的问题是 1)不易在任意方向的旋转轴插值; 2)万向节死锁;3)旋转的次序无法确定。
轴向角
轴角用一个以单位矢量定义的旋转角,再加上一个标量定义的旋转角来表示旋转。通常的表示[x,y,z,theta],前面三个表示轴,最后一个表示角度。表示非常直观,也很紧凑。
轴角最大的一个局限就是不能进行简单的插值,此外,轴角形式的旋转不能直接施于点或矢量,必转换为矩阵或者四元数。
四元数
四元数感觉上就是轴角的进化,也是使用一个3维向量表示转轴和一个角度分量表示绕此转轴的旋转角度,即(x,y,z,w), 其中
w = cos(theta/2)    
x  = a_x * sin(theta/2)    
y  = a_y * sin(theta/2)    
z  = a_z * sin(theta/2)  
其中(a_x,a_y,a_z)表示轴的矢量,theta表示绕此轴的旋转角度。四元数中的每个数都是经过“处理”的轴和角,轴角描述的“四元组”并不是一个空间下的东西,
首先(a_x,a_y,a_z)是一个3维坐标下的矢量,而theta则是级坐标下的角度,简单的将他们组合到一起并不能保证他们插值结果的稳定性,
因为他们无法归一化,所以不能保证最终插值后得到的矢量长度(经过旋转变换后两点之间的距离)相等,而四元数在是在一个统一的4维空间中,方便归一化来插值,
又能方便的得到轴、角这样用于3D图像的信息数据,所以用四元数再合适不过了。相比于矩阵,四元数也只要存储4个浮点数,优势很明显。
四元数的乘法,两个四元数q1、q2 https://baike.baidu.com/item/%E5%9B%9B%E5%85%83%E6%95%B0/5795379?fr=aladdin
方法一:相乘后展开(遵循下面规则)
1)i*i=-1(i,j,k轮换类似) 1*1=1
2)1*i=i*1=i(i,j,k轮换类似)
3)i*j=k,j*i=-k(i,j,k轮换类似) 
方法二:写成行列式形式
i  j  k  1
x1 y1 z1 w1
x2 y2 z2 w2
计算遵循行列式法则
计算结果:
q1 * q2 =
(w1*w2 - x1*x2 - y1*y2 - z1*z2) +
(w1*x2 + x1*w2 + y1*z2 - z1*y2) i +
(w1*y2 - x1*z2 + y1*w2 + z1*x2) j +
(w1*z2 + x1*y2 - y1*x2 + z1*w2) k
方法三:
q1 * q2 =(S1 + V1)*(S2 + V2) = S1.S2 - V1.V2 + V1XV2 + S1.V2 + S2.V1
其中q1=(S1 + V1)
q2=(S2 + V2)


四元数点积: p.q=s1.s2+v1.v2=w1*w2 + x1*x2 + y1*y2 + z1*z2=(p*q+q*p)/2
四元数外积:Outer(p,q)=(p*q-q*p)/2=s2.v1-s1.v2-v1Xv2
四元数偶积:Even(p,q)
四元数叉积也称为奇积


四元数的各种转换
四元数转欧拉角(y,p,r)->全部希腊字母读音
https://www.zybang.com/question/60be2c56584d0b710fad7c263722a2b9.html
φ=y=atan2(2(wx+yz), 1-2(xx+yy))
θ=p=arcsin(2(wy-zx))
ψ=r=atan2(wz+xy), 1-2(yy+zz))
欧拉角转四元数(w,x,y,z)
w=cos(φ/2)cos(θ/2)cos(ψ/2)+sin(φ/2)sin(θ/2)sin(ψ/2)
x=sin(φ/2)cos(θ/2)cos(ψ/2)-cossinsin
y=cos(φ/2)sin(θ/2)cos(ψ/2)+sincossin
z=cos(φ/2)cos(θ/2)sin(ψ/2)-sinsincos


四元数转旋转矩阵
Matrix4x4(
1.0f - 2.0f*y*y - 2.0f*z*z, 2.0f*x*y - 2.0f*z*w, 2.0f*x*z + 2.0f*y*w, 0.0f,
2.0f*x*y + 2.0f*z*w, 1.0f - 2.0f*x*x - 2.0f*z*z, 2.0f*y*z - 2.0f*x*w, 0.0f,
2.0f*x*z - 2.0f*y*w, 2.0f*y*z + 2.0f*x*w, 1.0f - 2.0f*x*x - 2.0f*y*y, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
)


unity3d
(x,y,z)=(i,j,k)=(向左L,向上U,向外F)
欧拉角(y,p,r)
pitch俯仰角=z轴正方向=xy平面绕z轴
yaw偏航角=y轴正方向=xz平面绕y轴
roll滚动角=x轴正方向=yz平面绕z轴


法矢量
ij=k
发布了71 篇原创文章 · 获赞 8 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/QQ18334373taikongyi/article/details/78060111