【UGUI】一键对齐父节点

前端时间用了一阵FairyGUI,实话实说感觉非常友好!首先他提供了一个编辑器,各种拼接、动画==都做得很棒,而且,还具有跨平台的特点,代码接口做的也很完善,虽然很多坑,但是在群里和谷主联系后几乎都没毛病(此处有表情)。但是,本次新项目还是选择了UGUI,因为说是虽然简单、但是再招人补充人手时还得重头学。。。其实当时我也就看了一上午0.0

这两天用UGUI做Demo,虽然不求做的好看但是至少得有个对齐什么的吧,但是每次修改对齐时拖拖拖很麻烦,蛋疼没有一键对齐,于是乎,只能自己动手。

每个UI组件的共同特点是都有一个RectTransform,, 所以,我们的目标是扩展RectTransform的 Inspector 面板,加上相应的对齐按钮就OK了。思路有了,当操作的时候遇到了一个问题,系统自带的油了一个RectTransformEditor ,如果我们要重写的话会覆盖原来的,而且我们也没法继承系统的那个editor。试了好多种方法,最后,在 MoMo的博客里找到了解决方案 : 

Unity3D研究院编辑器之不影响原有布局拓展Inspector(二十四)


通过反射获取相关信息,实现后我们的效果是:

【UGUI】一键对齐父节点_第1张图片


RectTransform的下方添加一个 “AlignParent” ,里面九个表示 相对于 父节点 的对齐。

具体代码如下:

///
/// Author:Cheng
/// Time:2017/2/27
/// Des:扩展RectTransform,一键对齐
/// 

using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(RectTransform))]
public class GUIAlignment : DecoratorEditor
{
    /// 
    /// 继承自类DecoratorEditor,做反射获取RectTransformEditor内属性、方法
    /// 
    public GUIAlignment() : base("RectTransformEditor") { }
    /// 
    /// 修改Inspector面板
    /// 
	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();

        
	}

    /// 
    /// 设置位置
    /// 1 2 3
    /// 4 5 6
    /// 7 8 9
    /// 
    /// 操作的UI
    /// 父节点
    /// 九宫格位置
    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。

你可能感兴趣的:(UGUI)