UGUI 有它的实用性, 可是也存在理解上的困难, 因为它在面板上的显示内容根据布局而变动, 如果不深入理解它的设计原理, 估计每次要进行程序上的修改都需要进行一次换算和测试过程.

1. 设置某UI的尺寸.

  它并没有提供一个直接设置尺寸的API, 因为想要改变UI大小根据需求有不同的方法, 不同的方法会造成不同的结果. 比如可以修改 anchorMin / anchorMax , 或是修改 offsetMax / offsetMin, 又或是修改 sizeDelta, 有多种可能的方案, 可是某些修改是会对子节点的UI造成很大影响的, 我们需要找到一个比较稳定的修改方法. Anchors相关的变量会造成子节点变化, 不应该修改它, 而offsetMax / offsetMin 跟 sizeDelta 其实可以看成是相同的表达, 只不过表现形式不一样. 那么简化的函数就是 :

public static void SetSize(RectTransform rect, Vector2 targetSize)
{
var originSize = rect.rect.size - rect.sizeDelta;
var makeSizeDelta = targetSize - originSize;
rect.sizeDelta = makeSizeDelta;
}

  只需要几次减法即可设置非常方便, 它的逻辑就是依据sizeDelta的性质来计算的 : sizeDelta 代表的是Rect现在的大小与原始Rect的大小的差, 公式应该是:

  RectSize(原始大小) + sizeDelta = RectSize(当前大小)

  那么我们要设置一个目标大小, 只需要先计算出原始大小, 然后用 RectSize(目标大小) - RectSize(原始大小) = sizeDelta 即可得出要得到目标大小时的sizeDelta, 直接设置给rect的sizeDelta 即可, 这样计算又简单, 又不需要改动锚点等, 保证修改过程的稳定性... 顺带一提 sizeDelta 绝对不是UI的大小, 是UI现在的大小跟UI的原始大小的差, 只有在锚点 anchorMin , anchorMax 相等时, UI 的原始大小为0, sizeDelta才跟UI大小相等.

2. 用UI的某个 Pivot 去跟父节点UI的某个 Pivot去对齐

  看起来很乱来的需求, 看图理解:

  子UI红色的 Pivot为 (0, 1), 而我们要把它的 (0.5, 1.0) 与父UI 的(0, 1) 的位置对齐, 也就是红色UI的中间顶部跟白色UI的左上角对齐, 修改方式也有很多种, 通过修改 anchoredPosition 应该是最稳健的方法了, 因为它不会修改任何造成子节点UI变化的变量. 简化的计算方法如下:

public static Vector2 SyncPovitToParent(RectTransform rect, Vector2 pivot, Vector2 parentPivot)
{
var parent = rect.parent as RectTransform;
var offsetInParent = MathTools.Multiple(MathTools.Multiple(rect.pivot, rect.rect.size) - MathTools.Multiple(pivot, rect.rect.size), rect.localScale);
var parentOffset = MathTools.Multiple(parentPivot, parent.rect.size) - MathTools.Multiple(rect.pivot, parent.rect.size);
return MathTools.VectorAdd(parentOffset, offsetInParent);
}

  MathTools 只是做了Vector对应变量的乘法加法等功能.

  这个方法的好处在于你不需要修改 Pivot 变量, 只通过移动UI的方式来进行对齐, 没有用到距离, 除法等...

rect.anchoredPosition = SyncPovitToParent(rect, new Vector2(0.5f, ), new Vector2(, ));

  rect 就是要对齐的红色UI, new Vector2(0.5f, 1) 是选定红色UI的Pivot位置( rect的原始Pivot为(0, 1), 计算前后不变 ),  new Vector2(0, 1) 是选定父节点UI的Pivot位置, 计算后rect相应的位置与父节点相应位置重合. 逻辑如下 :

1. 计算在当前Pivot下怎样移动rect才能使当前 Pivot 与父节点相应 Pivot 点重合

var parentOffset = MathTools.Multiple(parentPivot, parent.rect.size) - MathTools.Multiple(rect.pivot, parent.rect.size);

  直接用 parent.rect.size 作为坐标系, 乘上 parentPivot, rect.pivot 作为向量, 相减得出 rect 要移动的向量 parentOffset.

2. 计算在当前Pivot下, 怎样移动rect 才能让当前Pivot 与选定红色UI的 Pivot 位置重合

var offsetInParent = MathTools.Multiple(MathTools.Multiple(rect.pivot, rect.rect.size) - MathTools.Multiple(pivot, rect.rect.size), rect.localScale);

  使用当前UI大小作为坐标系, 乘上 rect.pivot, pivot 作为向量, 相减得到 rect 坐标系中的偏移量, 然后再乘以当前坐标的缩放 rect.localScale 就得到在父UI中 rect 要移动的向量 offsetInParent.

两个向量相加得到最后要偏移的量 anchoredPosition ...

UGUI 逻辑以及实用性辅助功能的更多相关文章

  1. Unity中uGUI的控件事件穿透逻辑

    1.正常来说Image和Text是会拦截点击事件的,假设加入EventTrigger的话,就能够响应相应的交互事件. 2.假设Image和Text是一个Button的子控件.那么尽管其会显示在Butt ...

  2. Unity进阶技巧 - 动态创建UGUI

    前言 项目中有功能需要在代码中动态创建UGUI对象,但是在网上搜索了很久都没有找到类似的教程,最后终于在官方文档中找到了方法,趁着记忆犹新,写下动态创建UGUI的方法,供需要的朋友参考 你将学到什么? ...

  3. 【Unity3D基础】让物体动起来①--UGUI鼠标点击移动

    背景 首先还是先声明自己是比较笨的一个人,总是找不到高效的学习方法,目前自己学习Unity3D的方式主要是两种,一种是直接看高质量的源码,另一种是光看不行还要自己动手,自己写一些有代表性的小程序,这也 ...

  4. Unity NGUI和UGUI与模型、特效的层级关系

    目录 1.介绍两大UI插件NGUI和UGUI 2.unity渲染顺序控制方式 3.NGUI的控制 4.UGUI的控制 5.模型深度的控制 6.粒子特效深度控制 7.NGUI与模型和粒子特效穿插层级管理 ...

  5. Unity UGUI —— 无限循环List

    还记得大学毕业刚工作的时候是做flash的开发,那时候看到别人写的各种各样的UI组件就非常佩服,后来自己也慢慢尝试着写,发现其实也就那么回事.UI的开发其实技术的成分相对来说不算多,但是一个好的UI是 ...

  6. Accessibility辅助功能--一念天堂,一念地狱

    0x00什么是Accessibility(辅助功能) 考虑到部分用户不能很好地使用Android设备,比如由于视力.身体.年龄方面的限制,造成阅读内容.触控操作.声音信息等方面的获取困难,Androi ...

  7. 如何简单的实现新手引导之UGUI篇

    一个完整的游戏项目肯定是要做新手引导的,而引导做的好坏可能会影响玩家的留存.那么怎么简单的实现个简有效的引导呢!先不说废话,先看看效果,这是一个基于UGUI做的一个简单的引导! 怎么样,看着是那么回事 ...

  8. 【渗透笔记】利用逻辑漏洞批量拿GOV EDU

    前言: 这个Oday是以前就有的,不过都没有人出过详细的使用教程,昨天帮群里某学院拿了他们的学校之后突然想起来这个Oday,而且实用性还很强,所以我就想分享到这里来了 关键字:inurl:sitese ...

  9. 《Java编程的逻辑》终于上市了!

    2018年1月下旬,<Java编程的逻辑>终于出版上市了! 这是老马过去两年死磕到底.无数心血的结晶啊! 感谢"博客园"的广大读者们,你们对老马文章的极高评价.溢美之词 ...

随机推荐

  1. 6.GC垃圾回收算法和垃圾收集器的关系

    JAVAGC垃圾回收机制和常见垃圾回收算法 推荐博客:JVM垃圾回收机制和常见垃圾回收算法 JVM的内存结构.垃圾回收算法

  2. 三、排序算法总结一(冒泡排序,插入排序,选择排序)(C++版本)

    一.引言 对于各种排序算法也算是有了一定的了解,所以这里做一个总结. 二.冒泡排序法. 这是比较经典的排序算法,主要是通过内外两层的循环比较,使得乱序变为顺序. 下面是一个测试代码 #include ...

  3. c# 第29节 类

    本节内容: 1:类是什么 2:声明类 3:类的使用 1:类是什么 2:声明类 在生产上的声明:如下操作   或者快捷操作 ctrl+shift+a 键 出现如下界面: 3:类的使用 using Sys ...

  4. js判断为空

    function isEmpty (va){    if("undefined" == va){        return true;    }    if(null == va ...

  5. ln -s 文件夹变成文件(txt) / linux 链接出错

    问题: 平时没有注意过这这个问题,当我使用ln -s xxx yyy  将xxx 移动到yyy 路径时,文件夹就变成了txt文件, 解决: 找了半天,在stackoverflow上找到了答案,很简单, ...

  6. 第04组 Alpha冲刺(1/4)

    队名:斗地组 组长博客:地址 作业博客:Alpha冲刺(1/4) 各组员情况 林涛(组长) 过去两天完成了哪些任务: 1.安排好各个组员的任务 2.收集各个组员的进度 3.写页面 4.写博客 展示Gi ...

  7. ksync

    #include <linux/init.h> #include <linux/module.h> #include <linux/types.h> #includ ...

  8. Java连载36-IDE使用

    一.主方法注意 每一个类都可以编写一个主方法,但是一般情况下,一个系统只有一个入口,所以主方法一般写一个 二.Myeclipse的使用 1.在workspace中工作区中有一个文件夹.metadata ...

  9. MAT 4378 – MAT 5317, Analysis of categorical

    MAT 4378 – MAT 5317, Analysis of categorical data, Assignment 3 1MAT 4378 – MAT 5317, Analysis of ca ...

  10. 明解C语言 入门篇 第十三章答案

    练习13-1 /* 打开与关闭文件 */ #include <stdio.h> int main(void) { ]; FILE* fp; printf("请输入你要打开的文件& ...