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. [原创]一种简单的cocos2d-x动态更新方案

    介绍一个曾经在cocos2d-x项目中使用过的动态更新方案,这个方案简单易行,针对小的项目非常有用. 这个方案有两个核心的关键词:JSON,MD5. 原理可以简单地概括为:服务端持有所有动态更新资源文 ...

  2. List 接口以及实现类和相关类源码分析

    List 接口以及实现类和相关类源码分析 List接口分析 接口描述 用户可以对列表进行随机的读取(get),插入(add),删除(remove),修改(set),也可批量增加(addAll),删除( ...

  3. 图像特征提取三大法宝:HOG特征,LBP特征,Haar特征

    (一)HOG特征 1.HOG特征: 方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子.它通过计算和 ...

  4. HW7.6

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...

  5. AVD Snapshot功能

    写程序的时候,经常会碰到:The application has stopped unexpectly… 有时候,会想对原来软件增加新功能或者修改bug.在eclipse修改后保存代码(注意,要保存所 ...

  6. A Tour of Go Interfaces are satisfied implicitly

    A type implements an interface by implementing the methods. There is no explicit declaration of inte ...

  7. Swift 基本语法1

    一.Swift简介 2010年的夏天,苹果公司的开发人员Chris Lattne接到了一个特别的任务,为OS X 和iOS平台开发下一代的编程语言,也就是Swift. 苹果公司于2014年WWDC(苹 ...

  8. AdapterView及其子类之二:使用ListActivity及ArrayAdapter创建列表

    见归档项目ListActivityDemo.zip. 基本步骤如下: 1.创建一个TextView,用于指定每一个ListView的格式 <?xml version="1.0" ...

  9. Android短彩信源码解析-短信发送流程(三)

    3.短信pdu的压缩与封装 相关文章: ------------------------------------------------------------- 1.短信发送上层逻辑 2.短信发送f ...

  10. iOS 9 学习系列:UIStack View (转载)

    作者:Nathan_Bao 地址:http://www.jianshu.com/p/1991e6c2881a 在 iOS9 中,Apple 引入了 UIStackView,他让你的应用可以通过简单的方 ...