1 尺寸与位置

通过UIWidget类获取,该类是所有UI元素的基类

在unity中创建一个sprite,如下图所示

这里面这个sprite的大小受几个属性的影响,首先是属性面板里的Size,对应的UIWidget成员为width和height字段,然后是其上层节点和自身scale属性。

1.1 局部大小

public override Vector3[] worldCorners
{
get
{
Vector2 offset = pivotOffset; float x0 = -offset.x * mWidth;
float y0 = -offset.y * mHeight;
float x1 = x0 + mWidth;
float y1 = y0 + mHeight; Transform wt = cachedTransform; mCorners[] = wt.TransformPoint(x0, y0, 0f);
mCorners[] = wt.TransformPoint(x0, y1, 0f);
mCorners[] = wt.TransformPoint(x1, y1, 0f);
mCorners[] = wt.TransformPoint(x1, y0, 0f); return mCorners;
}
}

从上面可以看出局部角点对应的矩形宽和长就等于width和height(mWidth等于width)

1.2 世界坐标系大小

所以计算某个UI元素在屏幕上的真实大小应该为

public override Vector3[] worldCorners
{
get
{
Vector2 offset = pivotOffset; float x0 = -offset.x * mWidth;
float y0 = -offset.y * mHeight;
float x1 = x0 + mWidth;
float y1 = y0 + mHeight; Transform wt = cachedTransform; mCorners[] = wt.TransformPoint(x0, y0, 0f);
mCorners[] = wt.TransformPoint(x0, y1, 0f);
mCorners[] = wt.TransformPoint(x1, y1, 0f);
mCorners[] = wt.TransformPoint(x1, y0, 0f); return mCorners;
}
}

从里面取两个四个角点之间的距离即可算出真实的大小(因为Transform类获取不到derived scale属性,只能获取到localScale属性)

上面代码中也用到了pivotOffset,该属性对应于在编辑器选中UI元素局部坐标系的原点,默认的情况下该值是(0.5,0.5),表示在UIWidget中的中心,为(0,0)表示在左下角,(1,1)表示在右上角。

同时根据上面的worldCorners也很好获取该UI元素在屏幕上的位置。这里面世界位置的计算中,可以看出同时用到了定义UI元素时的大小、坐标中心,以及该UI元素的转置矩阵。

所以说,假如需要改变UI元素的位置,只需改变其转置矩阵里的位置即可。

1.3 相对于其他元素的位置

采用通用的计算过程,即假如要计算B相对于A的位置,只需给出A和B的世界坐标PA和PB,那么B相对于A的位置即为 Rba = PB- PA。

NGUI里对应的代码如下:

public override Vector3[] GetSides (Transform relativeTo)
{
Vector2 offset = pivotOffset; float x0 = -offset.x * mWidth;
float y0 = -offset.y * mHeight;
float x1 = x0 + mWidth;
float y1 = y0 + mHeight;
float cx = (x0 + x1) * 0.5f;
float cy = (y0 + y1) * 0.5f; Transform trans = cachedTransform;
mCorners[] = trans.TransformPoint(x0, cy, 0f);
mCorners[] = trans.TransformPoint(cx, y1, 0f);
mCorners[] = trans.TransformPoint(x1, cy, 0f);
mCorners[] = trans.TransformPoint(cx, y0, 0f); if (relativeTo != null)
{
for (int i = ; i < ; ++i)
mCorners[i] = relativeTo.InverseTransformPoint(mCorners[i]);
}
return mCorners;
}

1.4 屏幕位置

上面讨论的位置均是3D空间的位置,而非屏幕上的位置。

要获取一个UI元素在屏幕上的位置,使用NGUI的摄像头将世界坐标转换到屏幕坐标

pt=UICamera.currentCamera.WorldToScreenPoint(pt);

对于置于世界原点的摄像机,它的光轴也穿过世界原点,假如使用

Vector3 screenPt = cam.WorldToScreenPoint(new Vector3(0,0,cam.nearClipPlane);

来计算光轴中心点在屏幕上的位置,可以发现算出来的屏幕位置也为屏幕中心,即(Screen.width/2,Screen.height/2,cam.nearClipPlane);

在NGUI中,2DUI的摄像机是正交摄像机,3D的才是透视摄像机。

同时正交摄像机中

屏幕的右上角对应的世界坐标为:

Vector3 worldPt = cam.ScreenToWorldPoint(newVector3(Screen.width,Screen.height,uiCam.nearClipPlane));

//worldPt = (cam.size*(Screen.width/Screen.height),cam.size,cam.nearClipPlane);

左下角的世界坐标为:

Vector3 worldPt1 = cam.ScreenToWorldPoint(newVector3(0,0,uiCam.nearClipPlane));

//worldPt = (-cam.size*(Screen.width/Screen.height),-cam.size,cam.nearClipPlane);

这里面假设的是相机填满整个屏幕,即相机的Rect属性的w和h均为1

2 实例

2.1 将UI移动屏幕指定像素位置

usingUnityEngine;
usingSystem.Collections; publicclassSetPos:MonoBehaviour { publicint targetX;
publicint targetY; public Camera uiCam;
private UIWidget ui; voidStart() { ui=GetComponent<UIWidget>();
SetScreenPosition(targetX, targetY);
}
voidSetScreenPosition(int x,int y)
{
Vector3 targetPos = uiCam.ScreenToWorldPoint(newVector3(x, y, transform.position.z));
Vector3 dir = targetPos - transform.position;
transform.Translate(dir);
}
voidSetScreenPosition1(int x,int y)
{
//使用线性映射计算目标位置
float w =Screen.width;
float h =Screen.height;
float posX = uiCam.orthographicSize* w / h;
float posY = uiCam.orthographicSize;
float targetX = x ** posX / w - posX;
float targetY = y ** posY / h - posY; Vector3 targetPos1 =newVector3(targetX, targetY,);
Vector3 dir = targetPos1 - transform.position;
transform.Translate(dir);
} }

【Unity3D NGUI】----UI尺寸和位置的调整的更多相关文章

  1. UI布局只关乎三件事情:尺寸、位置、组织

    UI布局只关乎三件事情:尺寸.位置.组织. 组织分为两类: 单元组织: 集合组织: 混合组织.

  2. Unity3d ngui基础教程

    Unity3d ngui基础教程 NGUI教程:步骤1-Scene 1.创建一个新的场景(New Scene).2.选择并删除场景里的MainCamera.3.在NGUI菜单下选择Create a N ...

  3. Unity3D NGUI自适应屏幕分辨率(2014/4/17更新)

    原地址:http://blog.csdn.net/asd237241291/article/details/8126619 原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 本文链接地址: ...

  4. Unity3D游戏UI开发经验谈

    原地址:http://news.9ria.com/2013/0629/27679.html 在Unity专场上,108km创始人梁伟国发表了<Unity3D游戏UI开发经验谈>主题演讲.他 ...

  5. web前端开发中常用的尺寸和位置

    我们在日常web前端开发过程中,会经常用到各种尺寸和位置.通常是js做动画的时候.轮播图,滚屏动画,粒子,碰撞检测,拖拽,滚动加载等等.这里我将常用的尺寸和位置的获取进行总结,不包括canvas,SV ...

  6. Unity3D NGUI学习(一)血条

    这次来讲讲Unity3D NGUI这个插件的学习,这个插件是收费的,不过去网上可以下载得很多可用版本.用来做用户的交互UI,学习起来比较简单 第一步,导入NGUI包 http://pan.baidu. ...

  7. 【转】Unity3D NGUI事件 UIEvents

    原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 QQ群:[119706192] 本文链接地址: Unity3D NGUI事件 UIEvents UIEvents-事件系统void OnH ...

  8. Windows窗口的尺寸和位置

    介绍 窗口的大小和位置表示为一个矩形边界,该矩形的坐标是相对于屏幕或父窗口而言的.顶级窗口的坐标是相对于屏幕的左上角而言的,子窗口的坐标则是相对于父窗口的左上角而言.应用程序创建窗口时(CreateW ...

  9. iPhone/iPad/Android UI尺寸规范 UI尺寸规范,UI图标尺寸,UI界面尺寸,iPhone6尺寸,iPhone6 Plus尺寸,安卓尺寸,iOS尺寸

    iPhone/iPad/Android UI尺寸规范 UI尺寸规范,UI图标尺寸,UI界面尺寸,iPhone6尺寸,iPhone6 Plus尺寸,安卓尺寸,iOS尺寸 iPhone界面尺寸 设备 分辨 ...

随机推荐

  1. [AGC028D](dp计数)

    题解点我 Code #include <bits/stdc++.h> typedef long long LL; typedef unsigned long long uLL; #defi ...

  2. java_第一年_JDBC(2)

    上篇说到,通过JDBC可实现java编程程序和mysql数据库进行连接并交互,而交互后所形成的结果集是通过ResultSet对象来操作的. 创建ResultSet对象: stmt = conn.cre ...

  3. Codeforces 1119C(思维)

    题面 传送门 分析 这种题的重点是寻找不变量 我们发现如果改变4个角,则每一行和每一列的xor和不会改变(1^0=0^1) 所以只要算出异或和然后比较就可以 代码 #include<iostre ...

  4. Python_pickle

    pickle是一个可以将任意一个对象存储在硬盘文件中的工具. 更新:Python3中用法变了:  https://www.cnblogs.com/fmgao-technology/p/9078918. ...

  5. harbar仓库的接口测试

    一.接口测试命令 api接口文档:https://github.com/goharbor/harbor/blob/release-1.7.0/docs/swagger.yaml 1)查看所属项目的信息 ...

  6. mysql 8.0.15忘记密码重置方法

    1.打开命令窗口cmd,输入命令:net stop mysql,停止MySQL服务, 2.开启跳过密码验证登录的MySQL服务 输入命令 mysqld --console --skip-grant-t ...

  7. PHP-不涉及第三个变量交换两个变量的值

    不涉及第三个变量交换两个变量的值 方法1:使用加减法 <?php $a = 1; $b = 2; $a = $a+$b; $b = $a-$b; $a = $a-$b; printf(" ...

  8. A Tutorial on Using the ALSA Audio API

    A Tutorial on Using the ALSA Audio API This document attempts to provide an introduction to the ALSA ...

  9. TMS320C6455BCTZA 原厂订购 原装正品

    作为一家科研公司,保证芯片的原厂品质和正规采购渠道是科学严谨的研发工作中重要的一环,更是保证研发产品可靠.稳定的基础.而研发中所遇到的各种不可预测的情况更是每个工程师向技术的山峰攀登中时会遇到的各种难 ...

  10. SpringBoot 快速支持国际化i18n

    学习目标 快速学会如何在工程中支持国际化语言. 快速查阅 专题阅读:<SpringBoot 布道系列> 源码下载:springboot-locale-i18n — Hey Man,Don' ...