Unity中屏幕坐标、视图坐标和世界坐标的相互转换
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Unity中屏幕坐标、视图坐标和世界坐标的相互转换,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3323字,纯文字阅读大概需要5分钟。
内容图文
![Unity中屏幕坐标、视图坐标和世界坐标的相互转换](/upload/InfoBanner/zyjiaocheng/1153/4e9d476f3ebe470886f9ddcdfd81677c.jpg)
我们在设计游戏的时候,经常会进行坐标系的变换,Unity为我们提供了多个变换的API,这里主要对它们的使用做一个总结整理!
在Unity中我们通常会用到以下几个坐标系下的点:
- 世界坐标系:World Space
- 简单来讲,我们通过
transform.position | transform.rotattion
获取得到的位置和旋转信息都是基于世界坐标系的,可以说,我们的很大一部分操作都是基于世界坐标系。
- 简单来讲,我们通过
- 观察坐标系:Eye Space
- 我们在Unity的Game视图中观察的画面始终是由摄像机提供的,基于摄像机的一个坐标系也就是"Eye Space"(简单来讲就是把摄像机看作原点位置)。
- ViewPort:View Port
- 视口是针对游戏显示的画面进行描述的,View Port用于描述整个游戏画面的坐标,左下角为
(0,0)
,右上角为(1,1)
,我们在设计分屏游戏的时候可以通过设置摄像机所占据的视口空间来控制。
- 视口是针对游戏显示的画面进行描述的,View Port用于描述整个游戏画面的坐标,左下角为
- 屏幕坐标系:Screen Space
-
- 屏幕坐标开始和像素扯上关系了,也就是说屏幕坐标和分辨率有关,屏幕的左下角为
(0,0)
,但右上角为(screen.width,screen.height)
。比如游戏的分辨率为500*600
,则screen.width=500;screen.height=600
。
- 屏幕坐标开始和像素扯上关系了,也就是说屏幕坐标和分辨率有关,屏幕的左下角为
Input.mousePosition
来获取鼠标的位置,
Vector3
类型的变量,但z
分量始终为0。
// 1.屏幕转世界坐标 Vector3 Camera.main.ScreenToWorldPoint(new Vector3(screenPos.x , screenPos.y , zInfo)); //2.世界转屏幕坐标 Vector3 Camera.main.WorldToScreenPoint(new Vector3(worldPos.x , worldPos.y , worldPos.z)); //3.世界转视口坐标Vector3 Camera.main.WorldToViewportPoint(); //4.视口转世界坐标 Vector3 Camera.main.ViewportToWorldPoint(new Vector3(viewPortPos.x , viewPortPos.y , zInfo)); //5.视口转屏幕坐标Vector3 Camera.main.ViewportToScreenPoint(); //6.屏幕转视口坐标 Vector3 Camera.main.ScreenToViewportPoint();
作者作为初学者的一员,认为先搞清楚这几个暂时足够,日后若有使用更多的变换,则再进行补充吧。
观察这些个函数,首先一个很明显的共同点,就是这些函数都是Camera
的成员函数,输入和输出都为Vector3
类型的变量。也即这些函数都是针对当前摄像机的一个变换操作。这很容易理解,因为3D游戏中的坐标从模型空间到最终的屏幕空间经过了model
,view
,projection
,以及之后的NDC变换
等,其中除model
是用于从模型空间到世界空间的变换外,之后的view
,projection
都是基于摄像机的。他们会随着使用相机的变化而变化。至于具体的内容,变化过程,这里不做过多描述,读者可以查看网上的相关文章。
当然,我们在使用这些API的时候,只需要清楚我们的输入和输出的内容及其关系就好了。
接下来,我们来聊一聊这些函数:
首先是屏幕坐标和世界坐标的相互转换:
WorldToScreenPoint函数接收一个世界空间下的位置信息,然后返回其所在的屏幕空间位置,以及其相对于摄像机的深度信息,该深度信息由世界空间下摄像机和输入位置的z值来决定。 一个例子是:摄像机的位置为( 0.0, 0.0 , -10.0),输入的位置为(0.0,0.0,1.0)。则返回的结果为(screen.width/2 , screen.height/2 , 1-(-10)); 注意摄像机指向-z方向! ScreenToWorldPoint则是与之相反,输入屏幕空间位置以及相应的深度信息(注意深度信息应该为目标z值金和相机z值的差值),可以返回其所在的世界坐标位置。
视口坐标和世界坐标与之相似:
WorldToViewportPoint:输入世界坐标,返回的是对应的点所在的视口位置,当然以及其相对于摄像机的深度信息(距离)
ViewportToWorldPoint:输入视口坐标(记得对应的深度信息),返回点所在的世界坐标
视口坐标和屏幕坐标非常简单,正如上面的说明,只要知道分辨率就可以轻松转换,这里不再赘述。
一个简单的应用
transform.position
,我们希望对物体的x
,y
两个轴向的移动进行限制(同时冻结物体的z轴移动)。一个简单的思路如下:public float leftBorder; public float rightBorder; public float topBorder; public float bottomBorder; .... Vector3 leftBtm_cornerPos = Camera.main.ViewportToWorldPoint(new Vector3(0f, 0f, Mathf.Abs(-Camera.main.transform.position.z))); //这里的z轴在正交视图下意义不大 Vector3 rightTop_cornerPos = Camera.main.ViewportToWorldPoint(new Vector3(1f, 1f, Mathf.Abs(-Camera.main.transform.position.z))); .... leftBorder = leftBtm_cornerPos.x; rightBorder = rightTop_cornerPos.x; topBorder = rightTop_cornerPos.y; bottomBorder = leftBtm_cornerPos.y; .... if (pos.x <= leftBorder) { pos.x = leftBorder; } elseif (pos.x >= rightBorde { pos.x = rightBorder; } if (pos.y <= bottomBorder) { pos.y = bottomBorder; } elseif (pos.y >= topBorder) { pos.y = topBorder; }
上面的代码通过ViewportToWorldPoint
获取到了四个边界。之后通过限制位置的x
、y
轴向移动就可以控制避免移动过度。
z
轴并无太大的作用。ViewportToWorldPoint
的时候使用0
作为z
轴数据,也一样没关系。但是对于透视投影就不太一样了。z
轴数据了!。
原文:https://www.cnblogs.com/joemono/p/13186660.html
内容总结
以上是互联网集市为您收集整理的Unity中屏幕坐标、视图坐标和世界坐标的相互转换全部内容,希望文章能够帮你解决Unity中屏幕坐标、视图坐标和世界坐标的相互转换所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。