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. oracle触发器学习

    转自:http://blog.csdn.net/indexman/article/details/8023740/ 本篇主要内容如下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触 ...

  2. cubla sample-code

    cublasSscal //Example 1. Application Using C and CUBLAS: 1-based indexing #include <stdlib.h> ...

  3. hdu4123-Bob’s Race(树形dp+rmq+尺取)

    题意:Bob想要开一个运动会,有n个房子和n-1条路(一棵树),Bob希望每个人都从不同的房子开始跑,要求跑的尽可能远,而且每条路只能走最多一次.Bob希望所有人跑的距离的极差不大于q,如果起点的编号 ...

  4. hdu4436-str2int(后缀数组 or 后缀自动机)

    题意:给你一堆字符串,仅包含数字'0'到'9'. 例如 101 123 有一个字符串集合S包含输入的N个字符串,和他们的全部字串. 操作字符串很无聊,你决定把它们转化成数字. 你可以把一个字符串转换成 ...

  5. EDM

    今天,夏令营需要发推广EDM. 之前的edm都是文字版, 今天摸索了一下,简单写了些码, 效果还不错. 演示:http://baike.baidu.com/cms/s/bkcampus/summerc ...

  6. hdoj 3790 最短路径问题

    最短路径问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  7. 低级错误之Hbm中类型不一致错误

    Myeclipse将数据库中的长整形生成为Bigdecimal类型,实际应该生成为Long.导致保存的时候报错.

  8. 在高版本SDK中打开现存低版本SDK工程

    直接打开低版本SDK工程会出现错误提示:“Unable to resolve target 'android-xx” 解决方法: 1.将project.properties文件中的“target=an ...

  9. sql STUFF用法

    sql STUFF用法 1.作用 删除指定长度的字符,并在指定的起点处插入另一组字符. 2.语法 STUFF ( character_expression , start , length ,char ...

  10. Spring Framework 5.0.0.M3中文文档 翻译记录 Part I. Spring框架概览1-2.2

    Part I. Spring框架概览 The Spring Framework is a lightweight solution and a potential one-stop-shop for ...