本随笔参考了以下博客,在此基础上进行优化和改进:

https://blog.csdn.net/qq_39640124/article/details/88284191

ugui中的Anchor预设如下:

允许我们快速对齐父物体的一部分轴向顶点或边,但有时我们并不是要对齐这些,而是需要对齐特定位置的某个点,例如:

如上图,上面的作战结束之后的等级信息B它应该是对齐父物体面板的什么位置呢?

当然了,你可以简单的将它设置为对齐屏幕右侧中点或者右上,那么此时无论屏幕分辨率如何改变,它的锚点Pivot距离屏幕右边缘的距离都不变。

但如果出现一种极端例子,屏幕的宽度小到比预设的距离还小,那么B早就跑到屏幕左侧去了。

显然,这样的Anchor预设调整是不太精准的,在屏幕分辨率改变较大时,很多不同对齐方式的元素有极大几率出现位置偏移甚至重叠。

ugui除了通过自带的预设,也可以手动输入Anchor的最大值和最小值来调整,当最大值和最小值相同时,它对齐的是相对百分比的一个点:

例如上面的B字母的中点精准的对齐方式是,距离父物体画布宽的82.9%高72.7%左右的位置,这样无论父物体随着分辨率如何改变,B的相对位置都保持不变。

值得注意的是,为了保证无任何偏移的可能,需要保证anchoredPosition为零,也就是面板中Pos为零。

但很遗憾的是,Unity编辑器暂时还没有办法自动对齐Anchor到物体的锚点Pivot或边框,当然了你可以每次尝试手动拖动,但保证你马上就会有口区的感觉,而且总会差那么一点对不齐。

下面是自动对齐的编辑器脚本,在网上参考了之前网友写过的对齐边框的写法,但发现只要锚点Pivot不在物件中心就会自动移动物体位置,在这里进行了一些优化修正,并增加了另一种对齐模式:

 using UnityEngine;
using UnityEditor; public class AnchorsAdapt
{
[MenuItem("Tools/AnchorsAdaptSize")]
private static void SelectionMS()
{
GameObject[] gos = Selection.gameObjects;
for (int i = ; i < gos.Length; i++)
{
if (gos[i].GetComponent<RectTransform>() == null)
continue;
AdaptSize(gos[i]);
}
} [MenuItem("Tools/AnchorsAdaptPivot")]
private static void SelectionMP()
{
GameObject[] gos = Selection.gameObjects;
for (int i = ; i < gos.Length; i++)
{
if (gos[i].GetComponent<RectTransform>() == null)
continue;
AdaptPivot(gos[i]);
}
} private static void AdaptPivot(GameObject go)
{
//------获取rectTransform----
RectTransform partentRect = go.transform.parent.GetComponent<RectTransform>();
RectTransform localRect = go.GetComponent<RectTransform>(); //位置信息
Vector3 partentPos = go.transform.parent.position;
Vector3 localPos = go.transform.position; float partentWidth = partentRect.rect.width;
float partentHeight = partentRect.rect.height; //---------位移差------
float offX = localPos.x - partentPos.x;
float offY = localPos.y - partentPos.y; float rateW = offX / partentWidth;
float rateH = offY / partentHeight;
var anchor = new Vector2(.5f + rateW, .5f + rateH);
localRect.SetRtAnchorSafe(anchor, anchor);
} private static void AdaptSize(GameObject go)
{
//位置信息
Vector3 partentPos = go.transform.parent.position;
Vector3 localPos = go.transform.position;
//------获取rectTransform----
RectTransform partentRect = go.transform.parent.GetComponent<RectTransform>();
RectTransform localRect = go.GetComponent<RectTransform>(); float partentWidth = partentRect.rect.width;
float partentHeight = partentRect.rect.height;
float localWidth = localRect.rect.width * 0.5f;
float localHeight = localRect.rect.height * 0.5f;
//---------位移差------
float offX = localPos.x - partentPos.x;
float offY = localPos.y - partentPos.y; float rateW = offX / partentWidth;
float rateH = offY / partentHeight;
localRect.anchorMax = localRect.anchorMin = new Vector2(0.5f + rateW, 0.5f + rateH);
localRect.anchoredPosition = Vector2.zero; //大小偏移
partentHeight = partentHeight * 0.5f;
partentWidth = partentWidth * 0.5f;
float rateX = (localWidth / partentWidth) * 0.5f;
float rateY = (localHeight / partentHeight) * 0.5f; //锚点偏移值
var pivotOffX = localRect.pivot.x-.5f;
var pivotOffY = localRect.pivot.y-.5f;
var pivotOff = new Vector2(localWidth * pivotOffX / partentWidth, localHeight * pivotOffY / partentHeight); localRect.anchorMax = new Vector2(localRect.anchorMax.x + rateX, localRect.anchorMax.y + rateY) - pivotOff;
localRect.anchorMin = new Vector2(localRect.anchorMin.x - rateX, localRect.anchorMin.y - rateY) - pivotOff;
localRect.offsetMax = localRect.offsetMin = Vector2.zero;
}
}

此脚本为编辑器Editor脚本,需要放在Editor文件夹下才能生效。其中安全设置Anchor的拓展方法如下:

     public static void SetRtAnchorSafe(this RectTransform rt, Vector2 anchorMin, Vector2 anchorMax)
{
if (anchorMin.x < || anchorMin.x > || anchorMin.y < || anchorMin.y > || anchorMax.x < || anchorMax.x > || anchorMax.y < || anchorMax.y > )
return; var lp = rt.localPosition;
//注意不要直接用sizeDelta因为该值会随着anchor改变而改变
var ls = new Vector2(rt.rect.width, rt.rect.height); rt.anchorMin = anchorMin;
rt.anchorMax = anchorMax; //动态改变anchor后size和localPostion可能会发生变化需要重新设置
rt.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, ls.x);
rt.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, ls.y);
rt.localPosition = lp;
}

Unity ugui Anchor锚点自动适配画布中的相对位置的更多相关文章

  1. Unity3D的UGUI布局锚点自动绑定关系

    [MenuItem("CONTEXT/RectTransform/Auto")] public static void AutoRectAnior() { Debug.Log(&q ...

  2. Unity ugui屏幕适配与世界坐标到ugui屏幕坐标的转换

    我们知道,如今的移动端设备分辨率五花八门,而开发过程中往往只取一种分辨率作为设计参考,例如采用1920*1080分辨率作为参考分辨率. 选定了一种参考分辨率后,美术设计人员就会固定以这样的分辨率来设计 ...

  3. Unity 基础-------------------------关于Anchor锚点的理解

    Unity进阶技巧 - RectTransform详解 Zui 关注 2016.02.17 01:27 字数 1704 阅读 22157评论 13喜欢 57赞赏 2 RectTransform属性一览 ...

  4. Unity UGUI Layout自动排版组件用法介绍

    Unity UGUI布局组件 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享 ...

  5. Unity UGUI —— 无限循环List

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

  6. Unity UGUI

    超详细的基础教程传送门:(持续更新中) Unity UGUI之Canvas&EventSystem:http://blog.csdn.net/qq992817263/article/detai ...

  7. Unity UGUI鼠标穿透UI问题(Unity官方的解决方法)

    简述 最近在用UGUI的时候遇到了鼠标穿透的问题,就是说在UGUI和3D场景混合的情况下,点击UI区域同时也会 触发3D中物体的鼠标事件.比如下图中 这里给Cube加了一个鼠标点击改变颜色的代码,如下 ...

  8. iOS 4s-6Plus屏幕自动适配及颜色转换为十六进制

    iOS各种屏幕自动适配及颜色转换为十六进制 ★★★XLJMatchScreen自动适配屏幕★★★ 支持pod导入 pod 'XLJScreenMatching', '~> 1.0.3' 如果发现 ...

  9. 【iOS开发】多屏尺的自动适配 AutoLayout (纯代码方式)

    关于AutoLayout,最早从iOS6开始引入使用.   主要功能是使用约束,对视图进行相对布局,以适应不同屏尺的变换.   网上大量的资料都在介绍xib和storyboard,如何使用AutoLa ...

随机推荐

  1. Java实现 LeetCode 541 反转字符串 II(暴力大法)

    541. 反转字符串 II 给定一个字符串和一个整数 k,你需要对从字符串开头算起的每个 2k 个字符的前k个字符进行反转.如果剩余少于 k 个字符,则将剩余的所有全部反转.如果有小于 2k 但大于或 ...

  2. Java实现 LeetCode 335 路径交叉

    335. 路径交叉 给定一个含有 n 个正数的数组 x.从点 (0,0) 开始,先向北移动 x[0] 米,然后向西移动 x[1] 米,向南移动 x[2] 米,向东移动 x[3] 米,持续移动.也就是说 ...

  3. Java实现 蓝桥杯 算法训练 1的个数

    试题 算法训练 1的个数 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 输入正整数n,判断从1到n之中,数字1一共要出现几次.例如1123这个数,则出现了两次1.例如15,那么从1 ...

  4. 第九届蓝桥杯JavaB组省赛真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.第几天 题目描述 2000年的1月1日,是那一年的第1天. 那么,2000年的5月4日,是那一年的第几天? 注意:需要提交的是一个整数 ...

  5. java算法集训结果填空题练习1

    1 空瓶换汽水 浪费可耻,节约光荣.饮料店节日搞活动:不用付费,用3个某饮料的空瓶就可以换一瓶该饮料.刚好小明前两天买了2瓶该饮料喝完了,瓶子还在.他耍了个小聪明,向老板借了一个空瓶,凑成3个,换了一 ...

  6. Linux 服务管理-服务分类

    Linux中的服务根据安装方法的不同可以分为RPM包默认安装的服务和源码包安装的服务,而RPM包安装的服务又依据启动和自启动的不同分为独立服务和基于xinetd服务. 查看已经安装的服务 查看所有RP ...

  7. ReentrantReadWriteLock(读写锁)全部源码注释

    package java.util.concurrent.locks; import java.util.concurrent.TimeUnit; import java.util.Collectio ...

  8. 读取Excel文件,抛出类似Cleaning up unclosed ZipFile for archive D:\project\myTest\autoAppUI\excelMode\用例模板2.xlsx 错误解决

    读excel用例的时候总报这个错误,一直不知道什么原因~~~~~~~~~~ 今天突然顿悟了,原来是读excel的时候用到了文件流,我在读文件的方法里加了流关闭的操作,完美解决报错

  9. 一口气说出9种分布式ID生成方式,面试官有点懵

    一.为什么要用分布式ID? 在说分布式ID的具体实现之前,我们来简单分析一下为什么用分布式ID?分布式ID应该满足哪些特征? 1.1.什么是分布式ID? 拿MySQL数据库举个栗子:在我们业务数据量不 ...

  10. Dubbo+Zookeeper集群案例

    一.开源分布式服务框架 1.Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以Spring框架无缝集成.    Dubbo是一款高性 ...