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. Session中短信验证码设置有效时间

    Session中短信验证码设置有效时间 package com.mozq.boot.kuayu01.controller; import org.springframework.web.bind.an ...

  2. MongoDB Java(七)

    在 Java 程序中如果要使用 MongoDB,你需要确保已经安装了 Java 环境及 MongoDB JDBC 驱动. mongodb-driver jar 下载地址:http://central. ...

  3. 线程休眠sleep

    一.sleep的作用 sleep() 定义在Thread.java中.sleep() 的作用是让当前线程休眠,即当前线程会从“运行状态”进入到“休眠(阻塞)状态”.sleep()会指定休眠时间,线程休 ...

  4. Python 对象比较(is & ==)

    Python 对象有 3 要素 id type value id 对象在内存中的地址 可以通过 id() 获取 比较 只有同一个对象 id 才会相同 id 通过 is 比较 示例: a = list( ...

  5. 【CometOJ】Comet OJ - Contest #8 解题报告

    点此进入比赛 \(A\):杀手皇后(点此看题面) 大致题意: 求字典序最小的字符串. 一场比赛总有送分题... #include<bits/stdc++.h> #define Tp tem ...

  6. Azure EA (1) 查看国内Azure账单

    <Windows Azure Platform 系列文章目录> 本文介绍的是国内由世纪互联运维的Azure China 有关Azure EA Portal的详细内容,可以参考我的GitHu ...

  7. Debug 路漫漫-12:Python: ValueError: 'userid' is both an index level and a column label, which is ambiguous.

    啊,又遇到难题了 == 想要对两个 dataframe 做自然连接 merge,连接的key 为 “userid”,但是报错:ValueError: 'userid' is both an index ...

  8. go modules包管理

    记录一下go工程迁移go modules的过程. go mod golang从1.11版本之后引入了包管理-go mod,并通过环境变量GO111MODULE 设置: 默认GO111MODULE 为a ...

  9. 读取指定页面中的超链接-Python 3.7

    #!/usr/bin/env python#coding: utf-8from bs4 import BeautifulSoupimport urllibimport urllib.requestim ...

  10. hdu-6071 Lazy Running

    In HDU, you have to run along the campus for 24 times, or you will fail in PE. According to the rule ...