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,当然,也完全可以做一些稍微复杂点的操作,根据情况更改代码即可
完整代码如下:
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();
}
}