Unity ugui Anchor锚点自动适配画布中的相对位置

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

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

 

ugui中的Anchor预设如下:

Unity ugui Anchor锚点自动适配画布中的相对位置

 

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

Unity ugui Anchor锚点自动适配画布中的相对位置

 

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

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

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

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

 

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

Unity ugui Anchor锚点自动适配画布中的相对位置

 

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

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

Unity ugui Anchor锚点自动适配画布中的相对位置

 

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

 

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

1 using UnityEngine; 2 using UnityEditor; 3 4 public class AnchorsAdapt 5 { 6 [MenuItem("Tools/AnchorsAdaptSize")] 7 private static void SelectionMS() 8 { 9 GameObject[] gos = Selection.gameObjects; 10 for (int i = 0; i < gos.Length; i++) 11 { 12 if (gos[i].GetComponent<RectTransform>() == null) 13 continue; 14 AdaptSize(gos[i]); 15 } 16 } 17 18 [MenuItem("Tools/AnchorsAdaptPivot")] 19 private static void SelectionMP() 20 { 21 GameObject[] gos = Selection.gameObjects; 22 for (int i = 0; i < gos.Length; i++) 23 { 24 if (gos[i].GetComponent<RectTransform>() == null) 25 continue; 26 AdaptPivot(gos[i]); 27 } 28 } 29 30 private static void AdaptPivot(GameObject go) 31 { 32 //------获取rectTransform---- 33 RectTransform partentRect = go.transform.parent.GetComponent<RectTransform>(); 34 RectTransform localRect = go.GetComponent<RectTransform>(); 35 36 //位置信息 37 Vector3 partentPos = go.transform.parent.position; 38 Vector3 localPos = go.transform.position; 39 40 float partentWidth = partentRect.rect.width; 41 float partentHeight = partentRect.rect.height; 42 43 //---------位移差------ 44 float offX = localPos.x - partentPos.x; 45 float offY = localPos.y - partentPos.y; 46 47 float rateW = offX / partentWidth; 48 float rateH = offY / partentHeight; 49 var anchor = new Vector2(.5f + rateW, .5f + rateH); 50 localRect.SetRtAnchorSafe(anchor, anchor); 51 } 52 53 private static void AdaptSize(GameObject go) 54 { 55 //位置信息 56 Vector3 partentPos = go.transform.parent.position; 57 Vector3 localPos = go.transform.position; 58 //------获取rectTransform---- 59 RectTransform partentRect = go.transform.parent.GetComponent<RectTransform>(); 60 RectTransform localRect = go.GetComponent<RectTransform>(); 61 62 float partentWidth = partentRect.rect.width; 63 float partentHeight = partentRect.rect.height; 64 float localWidth = localRect.rect.width * 0.5f; 65 float localHeight = localRect.rect.height * 0.5f; 66 //---------位移差------ 67 float offX = localPos.x - partentPos.x; 68 float offY = localPos.y - partentPos.y; 69 70 float rateW = offX / partentWidth; 71 float rateH = offY / partentHeight; 72 localRect.anchorMax = localRect.anchorMin = new Vector2(0.5f + rateW, 0.5f + rateH); 73 localRect.anchoredPosition = Vector2.zero; 74 75 //大小偏移 76 partentHeight = partentHeight * 0.5f; 77 partentWidth = partentWidth * 0.5f; 78 float rateX = (localWidth / partentWidth) * 0.5f; 79 float rateY = (localHeight / partentHeight) * 0.5f; 80 81 //锚点偏移值 82 var pivotOffX = localRect.pivot.x-.5f; 83 var pivotOffY = localRect.pivot.y-.5f; 84 var pivotOff = new Vector2(localWidth * pivotOffX / partentWidth, localHeight * pivotOffY / partentHeight); 85 86 localRect.anchorMax = new Vector2(localRect.anchorMax.x + rateX, localRect.anchorMax.y + rateY) - pivotOff; 87 localRect.anchorMin = new Vector2(localRect.anchorMin.x - rateX, localRect.anchorMin.y - rateY) - pivotOff; 88 localRect.offsetMax = localRect.offsetMin = Vector2.zero; 89 } 90 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wssgzd.html