Unity中的坐标转换
发布日期:2021-06-30 19:58:38
浏览次数:2
分类:技术文章
本文共 4976 字,大约阅读时间需要 16 分钟。
一:Unity中的四种坐标系
——世界坐标(World Space)
世界坐标很好理解,它是一个3D坐标。就是游戏物体在你创造世界中的坐标。transfrom.position获得的是物体相对于世界坐标的位置,transfrom.localPosition获得的是物体相对于父物体坐标的位置模型Mesh保存的顶点坐标均为局部坐标系下的坐标 ——屏幕坐标(Screen Space) 屏幕坐标是以像素来定义的,与分辨率有关,例如分辨率为1280*720的屏幕则Screen.width为1280,Screen.height为720。 Screen.width = Camera.main.pixelWidth和Screen.height = Camera.main.pixelHeight只有在相机视口坐标是整个屏幕时才满足。所以不难看出Screen.width是屏幕的分辨率即屏幕的宽度, 而Camera.main.pixelWidth是相机的视口像素大小,也可以理解为相机视口的像素宽度。屏幕的左下角坐标为(0 , 0),右上角为(Screen.width , Screen.height),z轴坐标是相机的世界坐标中z轴的负值我们常用的Input.mousePosition和移动端的Input.GetTouch(0).position都是获得的光标在屏幕坐标的位置 ——视口坐标(Viewport Space) 视口坐标系其实就是将屏幕坐标系单位化视口坐标的左下角为(0 , 0),右上角为(1 , 1),z轴坐标是相机的世界坐标中z轴的负值 可用于制作分屏游戏 ——GUI坐标 只作了解就好 它的原点在左上角为(0,0),右下角坐标为(Screen.width, Screen.height), 因为这是一个二维的坐标系,所以坐标z
的值永远都为0 二:各种坐标转换
——InverseTransformPoint和TransformPoin
例如物体A的世界坐标坐标为(1,2,3),物体B的世界坐标为(2,2,2),现在需要计算物体B相对于物体A的局部坐标,则应该使用A.transform.InverseTransformPoint(B) ——屏幕坐标转世界坐标Vector3 mousePos = Input.mousePosition;Vector3 screenToWorld = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, -Camera.main.transform.position.z));Debug.Log(screenToWorld);
——世界坐标转屏幕坐标
Vector3 worldToScreen = Camera.main.WorldToScreenPoint(transform.position);Debug.Log(worldToScreen);
——屏幕坐标转视口坐标
Vector3 mousePos = Input.mousePosition;Vector3 screenToViewport = Camera.main.ScreenToViewportPoint(mousePos);Debug.Log(screenToViewport);
——视口坐标转屏幕坐标
Vector3 viewportToScreen = Camera.main.ViewportToScreenPoint(new Vector3(1, 1, 0));Debug.Log(viewportToScreen);
——世界坐标转视口坐标
Vector3 worldToViewport = Camera.main.WorldToViewportPoint(transform.position);Debug.Log(worldToViewport);
——视口坐标转世界坐标
Vector3 viewportToWord = Camera.main.ViewportToWorldPoint(new Vector3(1, 1, -Camera.main.transform.position.z)); Debug.Log(viewportToWord);
——屏幕坐标转UI坐标
Vector2 mousePos;RectTransformUtility.ScreenPointToLocalPointInRectangle(transform.parent.GetComponent(), Input.mousePosition, null, out mousePos);Debug.Log(mousePos);
1.Canvas的RenderMode为Overlay时,cam参数应该为NULL。
2.rect必须为直接父物体任何一个坐标转世界坐标时,z的参数都应该为相机在世界坐标中z的负值
从世界坐标转到任何一个坐标时,计算出的z值都是相机的世界坐标中z轴的负值
三:屏幕坐标转世界坐标时为什么要使用-Camera.transform.position.z
任何一个坐标转世界坐标时的z值,可以理解为离相机的距离。其实是把屏幕坐标投影到相机的视锥体平面上,如果z的值为0,则相当于投影到了相机的近平面上,但是近平面的最小值为0.01,所以在进行屏幕坐标转世界坐标时,屏幕坐标的z值不能为0(注意Input.mousePosition的z值为0) 而且随着z的值越来越大,投影到的平面也会越来越大,x和y的值也会越来越大四:坐标转换的工具类
using UnityEngine;////// 坐标转换工具/// public static class CCUtils{ ////// 世界坐标转屏幕坐标 /// public static Vector2 World2Screen(Vector3 v, Camera camera = null) { if (camera == null) { camera = Camera.main; } Vector3 worldPos = v; Vector3 pos = camera.WorldToScreenPoint(worldPos); return pos; } ////// 屏幕坐标转世界坐标 /// public static Vector3 Screen2World(Vector2 v, Camera camera = null) { if (camera == null) { camera = Camera.main; } Vector3 screenPos = new Vector3(v.x, v.y, -camera.transform.position.z); Vector3 pos = camera.ScreenToWorldPoint(screenPos); return pos; } ////// 世界坐标转视口坐标 /// public static Vector2 World2Viewport(Vector3 v, Camera camera = null) { if (camera == null) { camera = Camera.main; } Vector3 worldPos = v; Vector3 pos = camera.WorldToViewportPoint(worldPos); return pos; } ////// 视口坐标转世界坐标 /// public static Vector3 Viewport2World(Vector2 v, Camera camera = null) { if (camera == null) { camera = Camera.main; } Vector3 viewportPos = new Vector3(v.x, v.y, -camera.transform.position.z); Vector3 pos = camera.ViewportToWorldPoint(viewportPos); return pos; } ////// 屏幕坐标转视口坐标 /// public static Vector2 Screen2Viewport(Vector2 v, Camera camera = null) { if (camera == null) { camera = Camera.main; } Vector3 screenPos = v; Vector3 pos = camera.ScreenToViewportPoint(screenPos); return pos; } ////// 视口坐标转屏幕坐标 /// public static Vector2 Viewport2Screen(Vector2 v, Camera camera = null) { if (camera == null) { camera = Camera.main; } Vector3 viewportPos = v; Vector3 pos = camera.ViewportToScreenPoint(viewportPos); return pos; } ////// 屏幕坐标转UI坐标 /// public static Vector2 Screen2UI(Vector2 v, RectTransform rect, Camera camera = null) { Vector2 pos; RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, v, camera, out pos); return pos; } ////// 世界坐标转UI坐标 /// public static Vector2 World2UI(Vector3 v, RectTransform rect, Camera uiCamera, Camera worldCamera = null) { if (worldCamera == null) { worldCamera = Camera.main; } Vector2 screenPos = World2Screen(v, worldCamera); Vector2 pos = Screen2UI(screenPos, rect, uiCamera); return pos; }}
转载地址:https://liuhaowen.blog.csdn.net/article/details/88124564 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2024年04月06日 23时51分16秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
PRM概率路线图
2019-04-30
ROS(六)——订阅者Subscriber的编程实现(C++ & Python)
2019-04-30
ROS(七)——话题消息的定义与使用
2019-04-30
yolov3入门实战
2019-04-30
B树 & B+树
2019-04-30
Node-Red(一)——简介与安装
2019-04-30
representation learning 表示学习/表征学习
2019-04-30
Haar特征
2019-04-30
Python 之 histogram直方图
2019-04-30
Python 之 Scatter散点图
2019-04-30
Python实现决策树 Desision Tree & 可视化
2019-04-30
决策树 Decision tree
2019-04-30
nominal和ordinal & 数据处理中四种基本数据类型
2019-04-30
Python 实现 Cross-validation
2019-04-30
Grid SearchCV(网格搜索)& Python实现
2019-04-30
ROS相关知识
2019-04-30