一键对齐父节点
前端时间用了一阵FairyGUI,实话实说感觉非常友好!首先他提供了一个编辑器,各种拼接、动画==都做得很棒,而且,还具有跨平台的特点,代码接口做的也很完善,虽然很多坑,但是在群里和谷主联系后几乎都没毛病(此处有表情)。但是,本次新项目还是选择了UGUI,因为说是虽然简单、但是再招人补充人手时还得重头学。。。其实当时我也就看了一上午0.0
这两天用UGUI做Demo,虽然不求做的好看但是至少得有个对齐什么的吧,但是每次修改对齐时拖拖拖很麻烦,蛋疼没有一键对齐,于是乎,只能自己动手。
每个UI组件的共同特点是都有一个RectTransform,, 所以,我们的目标是扩展RectTransform的 Inspector 面板,加上相应的对齐按钮就OK了。思路有了,当操作的时候遇到了一个问题,系统自带的油了一个RectTransformEditor ,如果我们要重写的话会覆盖原来的,而且我们也没法继承系统的那个editor。试了好多种方法,最后,在 MoMo的博客里找到了解决方案 :
Unity3D研究院编辑器之不影响原有布局拓展Inspector(二十四)
通过反射获取相关信息,实现后我们的效果是:
在RectTransform的下方添加一个 “AlignParent” ,里面九个表示 相对于 父节点 的对齐。
具体代码如下:
///
/// Author:Cheng
/// Time:2017/2/27
/// Des:扩展RectTransform,一键对齐
///
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(RectTransform))]
public class GUIAlignment : DecoratorEditor
{
/// <summary>
/// 继承自类DecoratorEditor,做反射获取RectTransformEditor内属性、方法
/// </summary>
public GUIAlignment() : base("RectTransformEditor") { }
/// <summary>
/// 修改Inspector面板
/// </summary>
public override void OnInspectorGUI ()
{
base.OnInspectorGUI ();
EditorGUILayout.BeginHorizontal();//横向
EditorGUILayout.LabelField("AlignParent");
EditorGUILayout.BeginVertical();//开始绘制九宫格
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();//first row
if (GUILayout.Button("┏", GUILayout.Width(25)))
{
RectTransform self = (RectTransform)target; //获得当前操作的transform,target是父中参数
if (self.parent != null)
{
RectTransform parent = (RectTransform)self.parent;
SetPos(self, parent, 1);
}
}
if (GUILayout.Button("┳", GUILayout.Width(25)))
{
RectTransform self = (RectTransform)target;
if (self.parent != null)
{
RectTransform parent = (RectTransform)self.parent;
SetPos(self, parent, 2);
}
}
if (GUILayout.Button("┓", GUILayout.Width(25)))
{
RectTransform self = (RectTransform)target;
if (self.parent != null)
{
RectTransform parent = (RectTransform)self.parent;
SetPos(self, parent, 3);
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();//second row
if (GUILayout.Button("┣", GUILayout.Width(25)))
{
RectTransform self = (RectTransform)target;
if (self.parent != null)
{
RectTransform parent = (RectTransform)self.parent;
SetPos(self, parent, 4);
}
}
if (GUILayout.Button("╋", GUILayout.Width(25)))
{
RectTransform self = (RectTransform)target;
if (self.parent != null)
{
RectTransform parent = (RectTransform)self.parent;
SetPos(self, parent, 5);
}
}
if (GUILayout.Button("┫", GUILayout.Width(25)))
{
RectTransform self = (RectTransform)target;
if (self.parent != null)
{
RectTransform parent = (RectTransform)self.parent;
SetPos(self, parent, 6);
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();//third row
if (GUILayout.Button("┗", GUILayout.Width(25)))
{
RectTransform self = (RectTransform)target;
if (self.parent != null)
{
RectTransform parent = (RectTransform)self.parent;
SetPos(self, parent, 7);
}
}
if (GUILayout.Button("┻", GUILayout.Width(25)))
{
RectTransform self = (RectTransform)target;
if (self.parent != null)
{
RectTransform parent = (RectTransform)self.parent;
SetPos(self, parent, 8);
}
}
if (GUILayout.Button("┛", GUILayout.Width(25)))
{
RectTransform self = (RectTransform)target;
if (self.parent != null)
{
RectTransform parent = (RectTransform)self.parent;
SetPos(self, parent, 9);
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
EditorGUILayout.EndHorizontal();
}
/// <summary>
/// 设置位置
/// 1 2 3
/// 4 5 6
/// 7 8 9
/// </summary>
/// <param name="self">操作的UI</param>
/// <param name="parent">父节点</param>
/// <param name="type">九宫格位置</param>
void SetPos(RectTransform self, RectTransform parent, int type)
{
//Vector2 max = self.anchorMax;
//Vector2 min = self.anchorMin;
Vector2 pos = self.anchoredPosition;//坐标点相对锚点位置
Vector2 p_middle = parent.sizeDelta*0.5f;//父节点的size的一半
p_middle.x = p_middle.x * parent.localScale.x; p_middle.y = p_middle.y * parent.localScale.y;//考虑到缩放
Vector2 s_middle = self.sizeDelta*0.5f;
s_middle.x = s_middle.x * self.localScale.x; s_middle.y = s_middle.y * self.localScale.y;
self.anchorMax = Vector2.one * 0.5f;//重置锚点位置为居中
self.anchorMin = Vector2.one * 0.5f;
self.anchoredPosition = Vector2.zero;//重置UI位置为正中
switch (type)
{
case 1:
pos.x = -(p_middle.x - s_middle.x);//因为unity的坐标采用左下角为坐标元点,故取负值
pos.y = (p_middle.y - s_middle.y);
break;
case 2:
pos.x = 0;
pos.y = (p_middle.y - s_middle.y);
break;
case 3:
pos.x = (p_middle.x - s_middle.x);
pos.y = (p_middle.y - s_middle.y);
break;
case 4:
pos.x = -(p_middle.x - s_middle.x);
pos.y = 0;
break;
case 5:
pos.x = 0;
pos.y = 0;
break;
case 6:
pos.x = (p_middle.x - s_middle.x);
pos.y = 0;
break;
case 7:
pos.x = -(p_middle.x - s_middle.x);
pos.y = -(p_middle.y - s_middle.y);
break;
case 8:
pos.x = 0;
pos.y = -(p_middle.y - s_middle.y);
break;
case 9:
pos.x = (p_middle.x - s_middle.x);
pos.y = -(p_middle.y - s_middle.y);
break;
}
self.anchoredPosition = pos;
// self.anchorMax = max;
// self.anchorMin = min;
}
}
除此之外,有一个 缺点,由于锚点是有两个相对坐标,分别为min、max,当UI拉伸时将会起相应的作用,所以,我要对齐时不能改变UI的大小,所以,锚点我会把它设置为中心,然后再改变位置,最后还有一个问题没解决,就是锚点初始设置不是中心时,改变位置后我再设置为原锚点会发现不对应的Bug,所以,改变位置后需要手动重新设置锚点。
that’s all。