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

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. Unity ugui屏幕适配与世界坐标到ugui屏幕坐标的转换

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

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

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

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

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

  4. Unity UGUI —— 无限循环List

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

  5. Unity UGUI

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

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

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

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

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

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

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

  9. 【译】UI设计基础(UI Design Basics)--自动适配与布局(Adaptivity and Layout)(四)

    2.3  自动适配与布局(Adaptivity and Layout) 2.3.1  开发成自动适配(Build In Adaptivity) 用户通常希望在自己的所有设备,各种场景中使用他们喜欢的a ...

  10. ## GridView 布局:item设置的高度和宽度不起作用、自动适配列数、添加Header和Footer ##

    一.item设置的高度和宽度不起作用 转自:http://www.cnblogs.com/0616--ataozhijia/p/6031875.html [Android Pro] listView和 ...

随机推荐

  1. eclipse 手动安装皮肤

    关于自动使用eclipse 主题不成功的给出现在手动的安装方法和jar包 http://pan.baidu.com/s/1kVNEiYr http://pan.baidu.com/s/1cyTZrS ...

  2. Linux Shell编程(27)——子shell

    运行一个shell脚本时会启动另一个命令解释器. 就好像你的命令是在命令行提示下被解释的一样, 类似于批处理文件里的一系列命令.每个shell脚本有效地运行在父shell(parent shell)的 ...

  3. cas 单点登录配置

    服务端配置 cas是个好东西,很灵活很好用,但是配置起来很麻烦 cas官方网站 http://downloads.jasig.org/ 下载服务端 CAS Server 3.3.3 Final 1.将 ...

  4. target vs currentTarget, clientWidth vs offsetWidth

    width: document < window(browser) < screen document--> clientWidth < offsetWidth(include ...

  5. Qt中用正則表達式来推断Text的语种,主要通过推断unicode的编码范围

    QString MainWindow::ParseLanguage(QString Text) {     if(Text.length()<=0)     {         return & ...

  6. 《Javascript网页经典特性300例》

    <Javascript网页经典特性300例> 基础篇 第1章:网页特性 刷新.后退.前进.关闭.标题.跳转禁止网页放入框架动态加载js避免浏览器使用缓存加载页面 第2章:DOM操作 根据n ...

  7. jquery.jqprint-0.3.js打印table表格遇到的坑

    在谷歌控制台输入window.print();可以调起当前整个页面的打印预览,那么要想打印页面某块区域内容怎么办呢? 我找到了jqprint插件,其原理是运用iframe 元素创建另外一个文档的内联框 ...

  8. Java遍历Map对象的方式

    public static void main(String[] args) { HashMap<String, String> testMap = new HashMap<> ...

  9. 前端学习 -- Html&amp;Css -- 框架集

    框架集和内联框架的作用类似,都是用于在一个页面中引入其他的外部的页面,框架集可以同时引入多个页面,而内联框架只能引入一个,在h5标准中,推荐使用框架集,而不使用内联框架. 使用frameset来创建一 ...

  10. [No0000FF]鸡蛋煮熟了蛋黄为什么发黑?

    你是否发现,鸡蛋煮熟后,蛋黄表面会呈现青黑色. 这是怎么回事? 这是因为鸡蛋的蛋白质富含有半胱氨酸,鸡蛋如果加热过度使半胱氨酸部分分解产生硫化氢,与蛋黄中的铁结合形成黑色的硫化铁.煮蛋中如果鸡蛋表面的 ...