前言

本篇文章主要是参考《Unity API 解析》---陈泉宏。

这是本人在学校图书馆找到一本书,主要介绍的就是常用的类,比较实用,没有冗余的地方。在此推荐一下这本书!

一、ScreenToViewportPoint方法

1、函数原型

  1. public Vector3 ScreenToViewportPoint(Vector3 position);

其中参数position为屏幕参考点。

2、功能说明

可以实现坐标点position从屏幕坐标系向摄像机视口的单位化坐标系转换。参考点position的x和y分量为屏幕的实际坐标值,单位为像素,z值无效。

3、实例演示

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class ScreenToViewportPoint_ts : MonoBehaviour {
  5.  
  6. // Use this for initialization
  7. void Start () {
  8.  
  9. transform.position = new Vector3(0.0f, 0.0f, 1.0f);
  10. transform.rotation = Quaternion.identity;
  11. //从屏幕的实际坐标向视口的单位化比例值转换
  12. Vector3 viewPortPoint = camera.ScreenToViewportPoint(new Vector3(Screen.width / 2.0f, Screen.height / 2.0f, 100.0f));
  13. Debug.Log("转换后的摄像机视口坐标系的坐标: " + viewPortPoint);
  14. //从视口的单位化比例值向屏幕的实际坐标点转换
  15. Vector3 screenPoint = camera.ViewportToScreenPoint(viewPortPoint);
  16. Debug.Log("转换后的屏幕坐标: " + screenPoint);
  17. Debug.Log("屏幕宽: " + Screen.width + " 屏幕高: " + Screen.height);
  18.  
  19. }
  20.  
  21. // Update is called once per frame
  22. void Update () {
  23.  
  24. }
  25. }

4、运行结果

二、ScreenToWorldPoint方法

1、函数原型

  1. public Vector3 ScreenToWorldPoint(Vector3 position);//position是参考点

2、功能说明

将参考点position从屏幕坐标系转换到世界坐标系。position中各个分量值都为实际单位像素值,而非比例值。

  1. Vector3 v = camera.ScreenToWorldPoint(ps);//ps为参考点
  2. //v的各个分量值为
  3. v.x = camera.transform.position.x + ps.z*asp*tan(e/);
  4. v.y = camera.transform.position.y + ps.z*tan(e/);
  5. v.z = camera.transform.position.z + ps.z;

其中e为摄像机的视口夹角fieldOfView的值,asp为摄像机视口的宽高比例值aspect。具体了解可以参考3D游戏与计算机图形学中的数学方法-视截体

3、实例演示

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class ScreenToWorldPoint_ts : MonoBehaviour
  5. {
  6.  
  7. // Use this for initialization
  8. void Start () {
  9.  
  10. transform.position = new Vector3(0.0f, 0.0f, 1.0f);
  11. camera.fieldOfView = 60.0f;
  12. camera.aspect = 1.6f;
  13. Debug.Log("z轴正方向100单位处对应的屏幕左下角的世界坐标值: " + camera.ScreenToWorldPoint(new Vector3(0.0f,0.0f,100.0f)));
  14. Debug.Log("z轴正方向100单位处对应的屏幕中间的世界坐标值: " + camera.ScreenToWorldPoint(new Vector3(Screen.width / 2.0f, Screen.height / 2.0f, 100.0f)));
  15. Debug.Log("z轴正方向100单位处对应的屏幕右上角的世界坐标值: " + camera.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, 100.0f)));
  16.  
  17. }
  18.  
  19. // Update is called once per frame
  20. void Update () {
  21.  
  22. }
  23. }

4、运行结果

三、ViewportToWorldPoint方法

1、函数原型

  1. public Vector3 ViewportToWorldPoint(Vector3 position);

2、功能说明

可以实现从Camera视口坐标点到世界坐标点转换,与WorldToViewportPoint的功能正好相反。此方法的返回值大小受当前Camera在世界坐标系中的位置、fieldOfVieew值以及参考点position的共同影响。其中参考点position的x和y分量的有效范围为[0.0,1.0],位比例值;而z值为实际单位值,而非比例值。

视口坐标点与世界坐标点的转换公式:

假设ps是视口坐标点,v是转换后对应ps的世界坐标点。那么有如下方程式:

  1. v.x = camera.transform.position.x + K1;
  2. v.y = camera.transform.position.y + K2;
  3. v.z = camera.transform.position.z + ps.z;
  4. 其中K1 = ps.z * asp * ((ps.x -0.5)/0.5)*tan(e/);
  5. K2 = ps.z * ((ps.y -0.5)/0.5)*tan(e/);
  6. e位摄像机的视口夹角fieldOfView的值,asp为摄像机视口的宽高比aspect

3、实例演示

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class ViewportToWorldPoint_ts : MonoBehaviour {
  5.  
  6. // Use this for initialization
  7. void Start () {
  8.  
  9. transform.position = new Vector3(1.0f, 0.0f, 1.0f);
  10. camera.fieldOfView = 60.0f;
  11. camera.aspect = 16.0f / 10.0f;
  12. Debug.Log("屏幕左下角: " + camera.ViewportToWorldPoint(new Vector3(0.0f, 0.0f, 100.0f)));
  13. Debug.Log("屏幕中间: " + camera.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 100.0f)));
  14. Debug.Log("屏幕右上角: " + camera.ViewportToWorldPoint(new Vector3(1.0f, 1.0f, 100.0f)));
  15.  
  16. }
  17.  
  18. // Update is called once per frame
  19. void Update () {
  20.  
  21. }
  22. }

4、运行结果

其余还有WorldToScreenPoint、WorldToViewportPoint等方法,使用如上面的例子类似,在此就不做阐述了。

四、关于Camera视口、aspect、pixelRect及Rect的解释

  • Camera视口用来记录当前摄像机能看到场景中的哪些内容,其大小及位置是可以改变的。而屏幕视口是指当前的硬件的屏幕,对于一个固定的硬件,它的屏幕视口大小(即分辨率)是固定的。Camera视口的内容不一定可以完全显示在屏幕上,屏幕可能只显示了一部分视口内容,也可能对视口内容进行了放缩。可以简单的理解为Camera视口是一张二维图片,而屏幕是用来显示这张图片的,图片可以被剪切,也可能被压缩。
  • Unity的Game面板中的aspect选项是用来模拟硬件屏幕的,可以分为三类即全屏显示、固定比例显示和固定分辨率显示。全屏显示即以当前Camera屏幕的大小来模拟硬件屏幕分辨率,其Camera视口即为当前摄像机的默认状态。而在固定比例方式则会改变Camera视口的宽高比,其大小不固定。而在固定分辨率方式下,其有效显示区间将保持固定分辨率的大小。

Camera屏幕分辨率的设置方式

  • 在Camera.aspect固定的情况下,无论选择Game视图中哪种屏幕模拟方式,它们的显示内容都是相同的。不同的屏幕模拟方式只会对显示的内容进行放缩。决定屏幕视口显示内容的是Camera.aspect的值和Camera.transform的属性,至于屏幕要如何显示Camera视口的内容,那就是硬件显示屏要处理的事情了。
  • PixelRect和Rect功能类似,都是决定硬件显示屏如何显示Camera视口提供的内容的。不同的是PixelRect是以实际像素来展示显示内容,而Rect是以单位化形式展示显示内容。

Unity中坐标系转换方法的更多相关文章

  1. 关于Unity中坐标系的种类

    坐标空间 1:物体空间: 3D物体自己的坐标空间 一般设计时几何体以中心为原点,人物以双脚为原点; 2: 世界空间: 3D物体在场景中的世界坐标, 整个游戏场景的空间; 3: 摄像机空间: 以观察摄像 ...

  2. maya和Unity中的坐标系旋转

    maya软件是用的右手坐标系,默认旋转顺序是ZYX,即先绕Z轴旋转,再绕Y轴旋转,最后绕X轴旋转. 比如在maya软件中,右侧的旋转顺序是可选的,默认的选择是“XYZ”,其实物体旋转顺序是倒着念,即上 ...

  3. Unity 中的坐标系

    说明: 注意几点: 0 行向量右乘矩阵与列向量左乘矩阵,两个矩阵互为逆矩阵 1 法线转换与mul,mul函数左乘矩阵当列矩阵计算,右乘当行矩阵计算 2 叉乘与左右手系,左手系用左手,右手系用右手,ax ...

  4. 解读Unity中的CG编写Shader系列八(镜面反射)

    转自http://www.itnose.net/detail/6117378.html 讨论完漫反射之后,接下来肯定就是镜面反射了 在开始镜面反射shader的coding之前,要扩充一下前面提到的知 ...

  5. 解读Unity中的CG编写Shader系列三

    转自http://www.itnose.net/detail/6096068.html 在上一个例子中,我们得到了由mesh组件传递的信息经过数学转换至合适的颜色区间以颜色的形式着色到物体上.这篇文章 ...

  6. unity中的欧拉角

    unity中欧拉角用的是heading - pitch -bank系统(zxy惯性空间旋转系统):当认为旋转顺序是zxy时,是相对于惯性坐标系旋转.当认为旋转顺序是yxz时,是相对于物体坐标系旋转. ...

  7. 【Unity编程】Unity中的欧拉旋转

    欧拉角的定义 在写这篇博客之前,我搜索了网上很多关于欧拉角的定义,发现大部分引用自维基百科的定义,我这里也引述一下: 维基百科定义 莱昂哈德·欧拉用欧拉角来描述刚体在三维欧几里得空间的取向.对于任何参 ...

  8. 骨骼动画的原理及在Unity中的使用

    制作骨骼动画 我们看看这几步操作后,我们得到了那些数据: 1.每个皮肤顶点的初始世界坐标. 2.每个骨骼关节顶点的初始世界坐标. 3.每个顶点被骨骼顶点的影响信息. 4.骨骼如何移动. 骨骼动画原理 ...

  9. unity中camera摄像头控制详解

    目录 1. 缘起 2. 开发 2.1. 建立项目 2.2. 旋转 2.2.1. 四元数 2.3. 移动 2.3.1. 向量操作 2.4. 镜头拉伸 2.5. 复位 2.6. 优化 1 缘起 我们的产品 ...

随机推荐

  1. CentOS 6.9升级GCC至7.3.0版本

    1.查看当前centos版本:  cat /etc/redhat-release 2. 安装centos6.9默认的开发工具,包含gcc,g++,make等等一系列工具: yum groupinsta ...

  2. [k8s] kubelet单组件启动静态pod

    kubelet单组件启动静态pod 无需k8s其他组件,单独下载kubelet的二进制,可以启动静态pod. 静态pod不受api管理,kubectl get po可以看到,但是kubectl del ...

  3. 【C语言】构造长度可变的二维数组

    #include <stdio.h> #include <malloc.h> #include <memory.h> int getArray(int ***p,i ...

  4. C++内联函数详解

    1.函数调用原理 "编译过程的最终产品是可执行程序--由一组机器语言指令组成.运行程序时,操作系统将这些指令载入计算机内存中,因此每条指令都有特定的内存地址.计算机随后将逐步执行这些指令.有 ...

  5. Solr学习之三 solr配置说明之一

    严格来说,我这篇内容,主要是根据Solr in Action关于配置的说明,以及参考Solr的wiki写的算是读书笔记吧,所有的图片默认来自Solr in Action这本书. 这本书我觉得对学习So ...

  6. nodejs字符串操作

    nodejs的字符串操作需要引入querystring对象,querystring对象的方法有: 1:querystring.stringify(“对象”,“分隔符”,“分配符”),用来将一个json ...

  7. linux tail -f 和 tail -F的区别 && tail 的断点续传

    bash-1中启动如下进程while [ "true" ] ; do date >> test.log; sleep 1 ; done; bash-2中,tail -f ...

  8. Centos7 squid安装与配置

    装squid yum install -y squid 安装httpd(用于后面生成密码文件) yum install -y httpd 或者 yum install httpd-tools -y 配 ...

  9. LeetCode: Min Stack 解题报告

    Min Stack My Submissions Question Solution Design a stack that supports push, pop, top, and retrievi ...

  10. python 在Unicode和普通字符串 str 之间转换

    unicodestring = u"Hello world" # 将Unicode转化为普通Python字符串:"encode" utf8string = un ...