2018-02-09 11:54:41 CJB_King 阅读数 426
屏幕坐标系和常用UI坐标系的转换

屏幕坐标转化为UGUI坐标:Unity提供一个方法,把屏幕坐标放入这个方法,就会返回出UGUI坐标​,就是这么简单

具体演示如下,实现一个拖动图片的功能:


2016-05-19 20:01:33 Gary_888 阅读数 702

Unity3D世界中的坐标系有四种:世界坐标系屏幕坐标系视口坐标系绘制UI界面的坐标系

1.世界坐标系

我们在场景中添加物体(Cube),他们都是以世界坐标显示在场景中。transform.position可以获取他们的世界坐标。

2.屏幕坐标

屏幕坐标是以像素为单位的,以屏幕左下角为(0,0),右上角为(Screen.width,Screen.height),z的位置是以相机的世界单位来衡量的。
注:鼠标位置坐标属于屏幕坐标,Input.mousePosition可以获得该位置坐标,手指触摸屏幕也为屏幕坐标,Input.GetTouch(0).position可以获得单个手指触摸屏幕的坐标。
Screen.width=Camera.pixelWidth;
Screen.height=Camera.pixelHeight;

3.ViewPort Space(视口坐标)

视口坐标是标准的和相对于相机的。相机的左下角为(0,0)点,右上角为(1,1)点,z的位置是以相机的世界单位来衡量的。

4.绘制GUI界面的坐标系

这个坐标与屏幕坐标相似,不同的是该坐标系以屏幕的左上角为(0,0)点,右下角为(Screen.width,Screen.height)。

四种坐标系的转换:

1.世界坐标→屏幕坐标:Camera.WorldToScreenPoint(transform.position);
2.屏幕坐标→视口坐标:Camera.ScreenToViewPortPoint(Input.GetTouch(0).position);
3.视口坐标→屏幕坐标:Camera.ViewportToScreenPoint();
4.视口坐标→世界坐标:Camera.ViewportToWorldPoint();

2018-06-22 13:09:21 lengyoumo 阅读数 3192

简述:本文会详细介绍三维软件中六种坐标的特点与关系,还有在脚本编辑和shader系统中的使用方法,还有些没有整理,预计2020年1月18日会再次更新

七种坐标系简介

unity 使用的是左手坐标系,即:
↑=Y,↓=-Y,前=Z,后=-Z,←=-X,→=X。

总共有六种坐标系,分别是模型坐标、世界坐标、观察坐标、裁剪坐标、屏幕坐标、ui坐标,uv坐标这七种坐标会按照一定顺序转换在程序中运行,实际上这就是模型从计算到在屏幕上显示的过程。

一 模型坐标

Local Space (模型坐标):就是一个模型自己的坐标,如果该模型下有子模型,则子模型也拥有自己的模型坐标,多个子模型在父模型下共享父坐标。
坐标:
模型原点为(0,0)
需要说明的是一个模型坐标的原点位置在创建模型的时候就定义好了。如果需要更改只能在blender或3dmax等建模软件中设定。unity是不能设置模型坐标原点的。
获取方式:
在unity脚本中:
transform.localPosition
在unity shader中:
顶点着色器默认输入的就是模型坐标

二 世界坐标

World Space(世界坐标):场景中的一切物体,包括模型,灯具,相机都共享一个绝对位置,这就是世界坐标。所有在模型坐标中的变化最终都会映射到世界坐标中。
坐标:
世界的中心点:0,0
获取方式:
在unity脚本中:
使用transform.position可以获得该位置坐标。
在unity shader中:
需要 将模型坐标转换为世界坐标才能获得。

三 观察坐标(视口坐标)

ViewPort Space (观察坐标):每个相机都是一个观察者,每个观察者都有自己的视界。
到这一步,会把世界坐标转换为以摄像机为参考的原点和方向。
坐标
左下角为(0,0)
右上角为(1,1)
Z的位置是以相机的世界单位来衡量的。
获取方式:

四 裁剪坐标

Clip Space (裁剪坐标):裁剪坐标是将观察世界的一部分截取出来。摄像机在取景的时候使用一个六面体去处理可视的区域,所有在这个区域的物体才会被显示。那么你肯定会有以为,为什么不直接用观察坐标,为什么一定要用这个裁剪呢? 首先,相机有两种模式,即透视相机与正交镜头(没有近大远小的透视效果)。这两种模式的切换会在裁剪坐标中处理。其次裁剪坐标规定了那些模型计算后可以显示,那些模型计算后但不用显示。所以必须有这个步骤。

五 屏幕坐标

Screen Space(屏幕坐标):屏幕坐标用于将裁剪坐标中的物体信息映射到屏幕上。我们知道三维世界是立体的,但不管是几维世界,只要实在屏幕上显示的就一定是2d的。
坐标:
左下角为(0,0)点
右上角为(Screen.width,Screen.height)
获取方式:
Z的位置是以相机的世界单位来衡量的。
  Screen.width = Camera.pixelWidth
  Screen.height = Camera.pixelHeigth

六 ui坐标

ui坐标是特殊的坐标系统,专门用于处理ui组件。ui坐标系是可视化窗口的最顶层,世界坐标系的物体都会被ui坐标系遮挡。
坐标:
左下角为(0,0)点
右上角为(Screen.width,Screen.height)
Z轴影响显示层级位置
获取方式:

七 uv坐标

相比之前的六种坐标系,uv坐标系只负责定位贴图和模型的关系
坐标:
左下角为(0,0)
右上角为(1,1)
获取方式:

【坐标系的转换】

1、世界坐标→屏幕坐标:

camera.WorldToScreenPoint(transform.position);这样可以将世界坐标转换为屏幕坐标。其中camera为场景中的camera对象。

public class Follow_2d3d : MonoBehaviour
{
    public GameObject f2d;
    public GameObject f3d;
    void Update()
    {
        Vector3 pos_3d = f3d.transform.localPosition;
        Vector3 screen_point = gameObject.GetComponent<Camera>().WorldToScreenPoint(pos_3d);
        f2d.transform.position = screen_point;
    }
}

该代码实现效果:ui中的2d元素会与三维物体重合,移动三维物体,2d元素会跟着移动

2、屏幕坐标→视口坐标:

camera.ScreenToViewportPoint(Input.GetTouch(0).position);这样可以将屏幕坐标转换为视口坐标。其中camera为场景中的camera对象。

public class Follow_2d3d : MonoBehaviour
{
    public GameObject f2d;
    public GameObject f3d;
    void Update()
    {
        Vector3 pos_2d = f2d.transform.position;
        Vector3 world_point = gameObject.GetComponent<Camera>().ScreenToWorldPoint(pos_2d);
        f3d.transform.position = world_point;
    }
}

该代码实现效果:ui中的2d元素会与三维物体重合,移动2d元素,三维物体会跟着移动

3、视口坐标→屏幕坐标:

camera.ViewportToScreenPoint();

4、视口坐标→世界坐标:

camera.ViewportToWorldPoint();
鼠标拖拽ui,不能直接使用position赋值。需要通过相机转换。

2015-07-26 10:03:06 xhyzdai 阅读数 847

左手坐标系

3D空间中,通过坐标确定物体所处的位置。U3D中采用的是左手坐标系。伸出左手,让拇指和食指成“L”形,大拇指向右,食指向上。其余的手指指向前方,这样就建立了一个左手坐标系。拇指、食指和其余手指分别代表x,y,z轴的正方向。
左手坐标系


U3D里的坐标系


为什么需要坐标转换


Transfrom组件


其他功能类


各种坐标之间的转换

世界坐标->屏幕坐标

世界坐标->UI坐标

世界坐标->本地坐标

本地坐标->世界坐标

2019-06-03 11:43:45 qq_37244872 阅读数 800

有时会有这样的需求,比如UI有一个坐标,如何去转成世界坐标呢,有人可能会想,直接transform.position不就行了吗,对,这样确实可以,然而如果只有这个坐标,却没有实体对象呢,比如把这个坐标作为炮弹的发射点,这时候,要如何去自己实现坐标系之间的转换呢。

首先我们需要借助unity的相机的坐标转换函数 ScreenToWorldPoint,这个API可以帮助我们把坐标系从屏幕坐标系转换成世界坐标系,这里的屏幕坐标系是指以窗口左下角作为起点(0,0),xy轴最大值分别为屏幕的宽度和长度的坐标系,距离我们的局部坐标还需要一个对应的转换关系,因为可能我们的画布并不是按照屏幕的分辨率来的,有时为了去做适配,我们可能会以高度作为基准去做适配,也就是Canvas里面的Canvas Scaler的UI Scaler Mode的scale with Screen Size,如果我们用了这种适配的方案,那么我们的画布就不是屏幕的分辨率的Size了而是预设给画布的Size,比如我之前给画布一个1280*720的Size,然后屏幕的分辨率却是ipad的分辨率2048*1536也就是4/3,在这种情况下,画布就是preHeight * Screen.width / Screen.height也就是720 * 2048 / 1536 = 960,这时候从画布坐标系到屏幕的坐标系的转换关系就很清晰了

屏幕坐标系坐标 = 画布局部坐标 * 拉伸比例(即从960 * 720 拉伸到2048 * 1536的比例) + 0.5 * 屏幕的宽高

也就是说,先把画布的局部坐标换成以画布中心为原点的坐标系,然后把坐标系原点移动到屏幕最左下角,如此一来,就得到屏幕的坐标系下的画布子对象局部坐标

再把计算出来的结果放入ScreenToWorldPoint 即是对应的世界坐标了

Unity3d UI系统

阅读数 58

Unity坐标系填坑

阅读数 117

没有更多推荐了,返回首页