Unity编辑器拓展

有时候为了加快效率,不得不做一些方便的小工具,尤其是有那种改变体属性,调整UI布局,或者调整字体,有选择性的添加修改组件的时候,如果一个两个手动该没问题,如果对象数量很多,而且只是做一些简单的更改的时候,那还是推荐大家先做一个工具,还能练练手。
时候会比如我们需要用铰链把一串transform连起来,或者把一些对象整齐排列,也可以先做一个工具。

如果需要一个窗体来输入设置信息的话,官方文档给出了大体的结构

using UnityEngine;
using UnityEditor;
using System.Collections;
class MyWindow : EditorWindow {
    [MenuItem ("Window/setpos")]
    public static void  ShowWindow () {
        EditorWindow.GetWindow(typeof(MyWindow),new Rect(0, 0, 300, 300));
    }
    void OnGUI () {
        // The actual window code goes here
    }
}

我们也可是设置快捷键,比如下面的shift+alt+ctrl+c

    //#shift &alt %Ctrl
    [MenuItem("Mytools/setpos #%&C")]

然后,我们再OnGUI函数中,添加文本输入框,按钮等对象

private void OnGUI()
    {
        GUI.Label(new Rect(62, 2, 60, 20), "x");
        GUI.Label(new Rect(122, 2, 60, 20), "y");
        GUI.Label(new Rect(184, 2, 60, 20), "z");
        GUI.Label(new Rect(2, 20, 60, 20), "startpos");
        xyzvalue[0] = GUI.TextField(new Rect(62, 20, 60, 20),xyzvalue[0]);
        xyzvalue[1]= GUI.TextField(new Rect(122, 20, 60, 20), xyzvalue[1]);
        xyzvalue[2] = GUI.TextField(new Rect(184, 20, 60, 20), xyzvalue[2]);
        GUI.Label(new Rect(62, 39, 60, 20), "x");
        GUI.Label(new Rect(122, 39, 60, 20), "y");
        GUI.Label(new Rect(184, 39, 60, 20), "z");
        GUI.Label(new Rect(2, 59, 60, 20), "step");
        xyzvalue[3] = GUI.TextField(new Rect(62, 59, 60, 20), xyzvalue[3]);
        xyzvalue[4] = GUI.TextField(new Rect(122, 59, 60, 20), xyzvalue[4]);
        xyzvalue[5] = GUI.TextField(new Rect(184, 59, 60, 20), xyzvalue[5]);
    }

效果
这条语句可以把选中的gameobjcet赋值给targetObject变量

targetObject = Selection.activeGameObject;//获得选中对象

然后,再button的单击事件中

        if (GUI.Button(new Rect(125, 200, 60, 30), "重新排列"))
        {
            startpos = new Vector3(float.Parse(xyzvalue[0]), float.Parse(xyzvalue[1]), float.Parse(xyzvalue[2]));
            xyzstep = new Vector3(float.Parse(xyzvalue[3]), float.Parse(xyzvalue[4]), float.Parse(xyzvalue[5]));
            targetObject = Selection.activeGameObject;//获得选中对象
            if (targetObject)
            {
                childObject.Clear();
                Getchild(targetObject.transform);

                foreach (Transform child in childObject)
                {
                    child.transform.position = startpos;
                    startpos += xyzstep;
                }
            }
            //Debug.Log("!!!");
        }

用一个递归来获取所有符合条件的子对象,比如我的条件是,tag为box,而且有transform组件,当然没有也可以通过代码添加。

static void Getchild(Transform tragetObject)
    {
        foreach(Transform child in tragetObject)
        {
            if (child.tag == "box" && child.GetComponent<Transform>()!=null)
            {
                childObject.Add(child);
            }
            if (child.childCount > 0)
            {
                Getchild(child);
            }
        }
    }

这个工具目前的功能是快速排列transform,当然,也完全可以做一些稍微复杂点的操作,根据情况更改代码即可
setpos
完整代码如下:

using UnityEditor;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Colorvalue:EditorWindow
{
    //#shift &alt %Ctrl
    [MenuItem("Mytools/setpos #%&C")]
    static void AddWindow()
    {
        Rect wr = new Rect(0, 0, 300, 300);
        Colorvalue window = (Colorvalue)EditorWindow.GetWindowWithRect(typeof(Colorvalue), wr, true, "setpos");
        window.Show();
    }
    static string[] xyzvalue = new string[6];
    static Vector3 xyzstep=Vector3.one;
    static Vector3 startpos = Vector3.zero;
    static GameObject targetObject;
    static List<Transform> childObject = new List<Transform>();
    static void Getchild(Transform tragetObject)
    {
        foreach(Transform child in tragetObject)
        {
            if (child.tag == "box" && child.GetComponent<Transform>()!=null)
            {
                childObject.Add(child);
            }
            if (child.childCount > 0)
            {
                Getchild(child);
            }
        }
    }
    private void OnGUI()
    {
        if (GUI.Button(new Rect(125, 200, 60, 30), "重新排列"))
        {
            startpos = new Vector3(float.Parse(xyzvalue[0]), float.Parse(xyzvalue[1]), float.Parse(xyzvalue[2]));
            xyzstep = new Vector3(float.Parse(xyzvalue[3]), float.Parse(xyzvalue[4]), float.Parse(xyzvalue[5]));
            targetObject = Selection.activeGameObject;//获得选中对象
            if (targetObject)
            {
                childObject.Clear();
                Getchild(targetObject.transform);

                foreach (Transform child in childObject)
                {
                    child.transform.position = startpos;
                    startpos += xyzstep;
                }
            }
            //Debug.Log("!!!");
        }
        GUI.Label(new Rect(62, 2, 60, 20), "x");
        GUI.Label(new Rect(122, 2, 60, 20), "y");
        GUI.Label(new Rect(184, 2, 60, 20), "z");
        GUI.Label(new Rect(2, 20, 60, 20), "startpos");
        xyzvalue[0] = GUI.TextField(new Rect(62, 20, 60, 20),xyzvalue[0]);
        xyzvalue[1]= GUI.TextField(new Rect(122, 20, 60, 20), xyzvalue[1]);
        xyzvalue[2] = GUI.TextField(new Rect(184, 20, 60, 20), xyzvalue[2]);
        GUI.Label(new Rect(62, 39, 60, 20), "x");
        GUI.Label(new Rect(122, 39, 60, 20), "y");
        GUI.Label(new Rect(184, 39, 60, 20), "z");
        GUI.Label(new Rect(2, 59, 60, 20), "step");
        xyzvalue[3] = GUI.TextField(new Rect(62, 59, 60, 20), xyzvalue[3]);
        xyzvalue[4] = GUI.TextField(new Rect(122, 59, 60, 20), xyzvalue[4]);
        xyzvalue[5] = GUI.TextField(new Rect(184, 59, 60, 20), xyzvalue[5]);
    }
    private void OnInspectorUpdate()
    {
        this.Repaint();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_33967521/article/details/86763058