• 【原】NGUI中的UIAnchor脚本功能


    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个中心像素点上。

     1             Rect rect = uiCamera.pixelRect;
     2             float cx = (rect.xMin + rect.xMax) * 0.5f;
     3             float cy = (rect.yMin + rect.yMax) * 0.5f;
     4             Vector3 v = new Vector3(cx, cy, depthOffset);
     5 
     6             if (side != Side.Center)
     7             {
     8                 if (side == Side.Right || side == Side.TopRight || side == Side.BottomRight)
     9                 {
    10                     v.x = rect.xMax;
    11                 }
    12                 else if (side == Side.Top || side == Side.Center || side == Side.Bottom)
    13                 {
    14                     v.x = cx;
    15                 }
    16                 else
    17                 {
    18                     v.x = rect.xMin;
    19                 }
    20 
    21                 if (side == Side.Top || side == Side.TopRight || side == Side.TopLeft)
    22                 {
    23                     v.y = rect.yMax;
    24                 }
    25                 else if (side == Side.Left || side == Side.Center || side == Side.Right)
    26                 {
    27                     v.y = cy;
    28                 }
    29                 else
    30                 {
    31                     v.y = rect.yMin;
    32                 }
    33             }

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

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

     1             float screenWidth  = rect.width;
     2             float screenHeight = rect.height;
     3 
     4             v.x += relativeOffset.x * screenWidth;
     5             v.y += relativeOffset.y * screenHeight;
     6 
     7             if (uiCamera.orthographic)
     8             {
     9                 v.x = Mathf.RoundToInt(v.x);
    10                 v.y = Mathf.RoundToInt(v.y);
    11 
    12                 if (halfPixelOffset && mIsWindows)
    13                 {
    14                     v.x -= 0.5f;
    15                     v.y += 0.5f;
    16                 }
    17             }
    18 
    19             // Convert from screen to world coordinates, since the two may not match (UIRoot set to manual size)
    20             v = uiCamera.ScreenToWorldPoint(v);
    21 
    22             // Wrapped in an 'if' so the scene doesn't get marked as 'edited' every frame
    23             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;
            }
        }
    }
    View Code

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

  • 相关阅读:
    Linux之文件处理命令
    Linux基础命令
    rip实验
    Linux基础之磁盘分区
    mysql安装
    centos Apache、php、mysql默认安装路径
    You probably tried to upload too large file. Please refer to documentation for ways to workaround this limit.
    Wrong permissions on configuration file, should not be world writable!
    机器会学习么 学习总结
    实验 5 Spark SQL 编程初级实践
  • 原文地址:https://www.cnblogs.com/basecn/p/NGUI_UIAnchor.html
Copyright © 2020-2023  润新知