UIAnchor的功能是把对象锚定在屏幕的边缘(左上,左中,左下,上,中,下,右上,右中,右下),或缩放物体使其匹配屏幕的尺寸。

在1.90版本后,拉长(缩放)的功能被放到UIStretch中,UIAnchor的功能更单一了,就是给对象定位。

借用《【Unity插件】NGUI核心组件之UIAnchor》文章中的内容:

NGUI:UIAnchor

Anchor脚本可以用来实现多个目的,这些在Example0里面都有用到。

1. 只要提供一个half-pixel偏移量,它可以让一个控件的位置在Windows系统上精确的显示出来(只有这个Anchor的子控件会受到影响)

2. 如果挂载到一个对象上,那么他可以将这个对象依附到屏幕的角落或者边缘

参数

UI Camera 是渲染这些对象的摄像机,如果没有手动设置,它会自动设置一个场景中的摄像机

Side 设置锚点,分别可以设置4个角,4个边和中心点

Half Pixel Offset 可以让对象在windows系统上显示的时候,有半个像素的偏移量。2D UI界面需要勾选上这个

Depth Offset 用来调整UIAnchor计算出来的位置的深度。它主要作用于基于透视的摄像机。这个值是世界坐标,与摄像机的远近裁切面类似

Relative Offset 相对偏移量 让你可以为物体设置以屏幕半分比为单位的偏移量

Tips

1. 如果一个对象上面挂载了一个UIAnchor,那么他的transform的值不能被手动修改-他们是被脚本控制的。如果你想对锚点加一个偏移量,那么给他添加一个子物体。举例来说,为了保证你的控件在一直在(100,100)的位置,你的对象结构应该是:UI->Anchor->Offset->Widget。

2. 如果你想将一个控件的位置设置为屏幕左边25%的位置,你可以将他设置为一个UIAnchor的子物体,这个UIAnchor的Side设置为Left,Relateive Offset 的X值设置为0.25。

脚本运行的前提是在UIRoot中能找到Camera对象,如果找不到就不会有任何效果。

定位只考虑屏幕的尺寸,并不考虑节点下的对象尺寸。默认情况下,UIAnchor附着在一个空的GameObject,脚本获得Camera的pixelRect属性(相机被渲染到屏幕像素中的位置),通过如下代码定位到屏幕边缘的8个像素点和1个中心像素点上。

             Rect rect = uiCamera.pixelRect;
float cx = (rect.xMin + rect.xMax) * 0.5f;
float cy = (rect.yMin + rect.yMax) * 0.5f;
Vector3 v = new Vector3(cx, cy, depthOffset); if (side != Side.Center)
{
if (side == Side.Right || side == Side.TopRight || side == Side.BottomRight)
{
v.x = rect.xMax;
}
else if (side == Side.Top || side == Side.Center || side == Side.Bottom)
{
v.x = cx;
}
else
{
v.x = rect.xMin;
} if (side == Side.Top || side == Side.TopRight || side == Side.TopLeft)
{
v.y = rect.yMax;
}
else if (side == Side.Left || side == Side.Center || side == Side.Right)
{
v.y = cy;
}
else
{
v.y = rect.yMin;
}
}

所以,如果在UIAnchor下的Panel中创建一个Button,默认情况把UIAnchor定位到左下,Button只会奇怪的露出1/4。因为Button的中心随着UIAnchor被定位在屏幕的左下角的像素上了。

另一个有用的参数是relativeOffset,这是个百分比参数。屏幕的宽和高被乘以偏移百分比后,加到记录屏幕中点的变量上,用有效的Camera转为对应的世界度坐标,并重新给UIAnchor来定位:

             float screenWidth  = rect.width;
float screenHeight = rect.height; v.x += relativeOffset.x * screenWidth;
v.y += relativeOffset.y * screenHeight; if (uiCamera.orthographic)
{
v.x = Mathf.RoundToInt(v.x);
v.y = Mathf.RoundToInt(v.y); if (halfPixelOffset && mIsWindows)
{
v.x -= 0.5f;
v.y += 0.5f;
}
} // Convert from screen to world coordinates, since the two may not match (UIRoot set to manual size)
v = uiCamera.ScreenToWorldPoint(v); // Wrapped in an 'if' so the scene doesn't get marked as 'edited' every frame
if (mTrans.position != v) mTrans.position = v;

UIAnchor的完整代码:

//----------------------------------------------
// NGUI: Next-Gen UI kit
// Copyright © 2011-2012 Tasharen Entertainment
//---------------------------------------------- using UnityEngine; /// <summary>
/// This script can be used to anchor an object to the side of the screen,
/// or scale an object to always match the dimensions of the screen.
/// </summary> [ExecuteInEditMode]
[AddComponentMenu("NGUI/UI/Anchor")]
public class UIAnchor : MonoBehaviour
{
public enum Side
{
BottomLeft,
Left,
TopLeft,
Top,
TopRight,
Right,
BottomRight,
Bottom,
Center,
} public Camera uiCamera = null;
public Side side = Side.Center;
public bool halfPixelOffset = true;
public float depthOffset = 0f;
public Vector2 relativeOffset = Vector2.zero; // Stretching is now done by a separate script -- UIStretch, as of version 1.90.
[HideInInspector][SerializeField] bool stretchToFill = false; Transform mTrans;
bool mIsWindows = false; /// <summary>
/// Legacy support.
/// </summary> void Start ()
{
if (stretchToFill)
{
stretchToFill = false; UIStretch stretch = gameObject.AddComponent<UIStretch>();
stretch.style = UIStretch.Style.Both;
stretch.uiCamera = uiCamera;
}
} /// <summary>
/// Automatically find the camera responsible for drawing the widgets under this object.
/// </summary> void OnEnable ()
{
mTrans = transform; mIsWindows = (Application.platform == RuntimePlatform.WindowsPlayer ||
Application.platform == RuntimePlatform.WindowsWebPlayer ||
Application.platform == RuntimePlatform.WindowsEditor); if (uiCamera == null) uiCamera = NGUITools.FindCameraForLayer(gameObject.layer);
} /// <summary>
/// Anchor the object to the appropriate point.
/// </summary> void Update ()
{
if (uiCamera != null)
{
Rect rect = uiCamera.pixelRect;
float cx = (rect.xMin + rect.xMax) * 0.5f;
float cy = (rect.yMin + rect.yMax) * 0.5f;
Vector3 v = new Vector3(cx, cy, depthOffset); if (side != Side.Center)
{
if (side == Side.Right || side == Side.TopRight || side == Side.BottomRight)
{
v.x = rect.xMax;
}
else if (side == Side.Top || side == Side.Center || side == Side.Bottom)
{
v.x = cx;
}
else
{
v.x = rect.xMin;
} if (side == Side.Top || side == Side.TopRight || side == Side.TopLeft)
{
v.y = rect.yMax;
}
else if (side == Side.Left || side == Side.Center || side == Side.Right)
{
v.y = cy;
}
else
{
v.y = rect.yMin;
}
} float screenWidth = rect.width;
float screenHeight = rect.height; v.x += relativeOffset.x * screenWidth;
v.y += relativeOffset.y * screenHeight; if (uiCamera.orthographic)
{
v.x = Mathf.RoundToInt(v.x);
v.y = Mathf.RoundToInt(v.y); if (halfPixelOffset && mIsWindows)
{
v.x -= 0.5f;
v.y += 0.5f;
}
} // Convert from screen to world coordinates, since the two may not match (UIRoot set to manual size)
v = uiCamera.ScreenToWorldPoint(v); // Wrapped in an 'if' so the scene doesn't get marked as 'edited' every frame
if (mTrans.position != v) mTrans.position = v;
}
}
}

原文地址:http://www.cnblogs.com/basecn/p/NGUI_UIAnchor.html

【原】NGUI中的UIAnchor脚本功能的更多相关文章

  1. 【原】NGUI中的UIRoot脚本功能

    UIRoot是NGUI控件的根节点,使用是根据屏幕尺寸自动(或手动)调节节点下子控件的大小. 这个组件声明了在编辑模式下运行:[ExecuteInEditMode],在Inspector编辑修改属性值 ...

  2. NGUI中Button与原生2D精灵的混合使用

    一些废话 每一篇的首段都是这个“一些废话”,原因是我太能逼逼了,不逼逼一些废话我就觉得难受.这是我第四篇关于Unity的博文,前两篇还是去年写的,“从一点儿不会开始”系列,类似教程和学习笔记的博文,这 ...

  3. Unity3D在NGUI中使用mask

    过程是这样的:最近一直想做一个头像的mask效果,后来发现原来unity的mask需要用shader来写,网上找了不少资料,也能实现,不过大多数都是用render texture作为相机投影的text ...

  4. 【Unity游戏开发】浅谈 NGUI 中的 UIRoot、UIPanel、UICamera 组件

    简介 马三最近换到了一家新的公司撸码,新的公司 UI 部分采用的是 NGUI 插件,而之前的公司用的一直是 Unity 自带的 UGUI,因此马三利用业余时间学习了一下 NGUI 插件的使用,并把知识 ...

  5. redis中使用java脚本实现分布式锁

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/115.html?1455860390 edis被大量用在分布式的环境中,自 ...

  6. 第二十三篇:在SOUI中使用LUA脚本开发界面

    像写网页一样做客户端界面可能是很多客户端开发的理想. 做好一个可以实现和用户交互的动态网页应该包含两个部分:使用html做网页的布局,使用脚本如vbscript,javascript做用户交互的逻辑. ...

  7. O365 "打开或关闭脚本"功能

    博客地址:http://blog.csdn.net/FoxDave 自定义功能是 SharePoint Online 最具吸引力的功能之一,因为它使管理员和用户可以调整网站和页面的外观以满足组织目 ...

  8. Web开发从零单排之二:在自制电子请帖中添加留言板功能,SAE+PHP+MySql

    在上一篇博客中介绍怎样在SAE平台搭建一个html5的电子请帖网站,收到很多反馈,也有很多人送上婚礼的祝福,十分感谢! web开发从零学起,记录自己学习过程,各种前端大神们可以绕道不要围观啦 大婚将至 ...

  9. 【Lucene3.6.2入门系列】第03节_简述Lucene中常见的搜索功能

    package com.jadyer.lucene; import java.io.File; import java.io.IOException; import java.text.SimpleD ...

随机推荐

  1. centos ssh 免密码登录

    最近在学习的过程中遇到这个问题: A主机和B主机: A 免密码登录B: 首先在A的 ~/.ssh 目录中 执行 ssh-keygen -t rsa 一路回车 最后生成连个文件: 将id_rsa.pub ...

  2. 【译】 AWK教程指南 附录A-Patterns

    awk 通过判断 Pattern 的值来决定是否执行其后所对应的Actions.这里列出几种常见的Pattern: A.1 BEGIN BEGIN 为 awk 的保留字,是一种特殊的 Pattern. ...

  3. 访问修饰符(access modifier)。

    1)public(公共的):被 public所修饰的属性和方法可以被有类访问. 所修饰的属性和方法可以被有类访问. 2)protected (受保护的):被protected所修饰的属性和方法可以在类 ...

  4. ./wls1036_linux32.bin: /lib/ld-linux.so.2: bad ELF interpreter

    [CentOS]安装软件:/lib/ld-linux.so.2: bad ELF interpreter解决   环境: [orangle@localhost Downloads]$ uname -m ...

  5. Django中的Model(操作表)

    Model 操作表 一.基本操作 # 增 models.Tb1.objects.create(c1='xx', c2='oo') #增加一条数据,可以接受字典类型数据 **kwargs obj = m ...

  6. Linux Pmap 命令:查看进程用了多少内存

    Pmap 提供了进程的内存映射,pmap命令用于显示一个或多个进程的内存状态.其报告进程的地址空间和内存状态信息.Pmap实际上是一个Sun OS上的命令,linux仅支持其有限的功能.但是它还是对查 ...

  7. SQL Server 2008数据库创建,备份,还原图解及注意点

    一.新建数据库 步骤1:点击“新建数据库”. 步骤2:输入数据库名称,设置数据库文件保存位置(注意点:最好自己设置数据库文件保存位置,不要采用安装时默认的文件保存位置!),点击“确认”即可完成新库的创 ...

  8. Stage3D学习笔记(七):动态纹理

    本章用来作为Starling的滤镜实现原理的一个补充,但是为了了解原理,我们会使用原生API进行编码. 我们知道,当我们调用drawTriangles方法时,我们的图像是绘制到后台缓冲区的,只有调用p ...

  9. C++学习笔记(一):头文件和源文件

    说明: 当一个源文件(a.cpp)要调用另一个源文件(b.cpp)定义的方法时,需要在a.cpp中写上这个方法的声明(只需要该方法的名称.返回值和参数,类似Java的接口): 如果每次调用其他文件的方 ...

  10. matlab inpolygon 判断点在多边形内

    如何判断一个点在多边形内部? xv= [0 3 3 0 0]; %x坐标 yv= [0 0 3 3 0];%y坐标 x=1.5; y=1.5; in=inpolygon(x,y,xv,yv) plot ...