Unity3D 自定义 Editor 扩展

《转载地址:ttp://www.omuying.com/article/130.aspx》

Unity3D 提供了强大的编辑器扩展机制,为了提高工作效率,我们可能会或多或少的进行编辑器扩展的开发,最常用的像打包 assetbundle 工具,因为原文部分代码有错误,为了让大家更好的理解这部分内容,本文对原作者的内容进行了修改以及补充,希望对您有所帮助。

第一种:ScriptableObject。相信大家一定用过这个,没有界面,代码如下:

using UnityEngine;
using UnityEditor;

public class ScriptableObjectDemo : ScriptableObject 
{
	//[MenuItem("GameObject/MainMenuItemDemo")] 去掉 callback 可以在 GameObject 菜单栏显示
	public static void MainMenuItemDemo(System.Action callback = null)
	{
		// 处理一些事情
		if(callback != null) callback("ScriptableObject Click!");
	}

	[MenuItem("Assets/ContextMenuItemDemo")]
	public static void ContextMenuItemDemo()
	{
		Debug.Log ("Project 面板 Assets 目录右键点击触发!");
	}
}



第二种:ScriptableWizard。ScriptableWizard 窗口最多可以定制两个按钮,一个是Create,另外一个称之为 Other。效果如图:

代码如下:

using UnityEngine;
using UnityEditor;

public class ScriptableWizardDemo : ScriptableWizard 
{
	public string ItemName;

	private static System.Action callback;

	//[MenuItem("GameObject/ScriptableWizardDemo")] 去掉 callback 可以在 GameObject 菜单栏显示
	public static void Init(System.Action callback = null)
	{
		ScriptableWizardDemo.callback = callback;
		ScriptableWizard.DisplayWizard (
			"ScriptableWizard Demo",
			"Submit",
			"Cancel"
		);
	}

	void OnWizardUpdate()
	{
		//
	}

	void OnWizardCreate()
	{
		if(ScriptableWizardDemo.callback != null)
		{
			ScriptableWizardDemo.callback(string.IsNullOrEmpty(this.ItemName) ? "空数据" : this.ItemName);
		}
	}

	void OnWizardOtherButton()
	{
		if(ScriptableWizardDemo.callback != null)
		{
			ScriptableWizardDemo.callback("面板关闭");
		}
		this.Close ();
	}
}


第三种:EditorWindow。EditorWindow 可以实现自由浮动和加入其他窗口的 tab,这种窗口的窗体功能和 Scene,Hierarchy 等窗口完全一致。效果如图:

与 ScriptableWizard 的区别如图:

代码如下:

using UnityEngine;
using UnityEditor;

public class EditorWindowDemo : EditorWindow 
{
	public int toolbarOption = 0;
	public string[] toolbarTexts = {"Tab One", "Tab Two", "Tab Three", "Tab Four"};

	private bool xCheckbox = true;
	private bool yCheckbox = true;
	private bool zCheckbox = true;

	private string itemName = null;

	private Transform itemObject = null;

	private Color itemColor = Color.white;

	private static System.Action callback;

	//[MenuItem("Window/EditorWindowDemo")] 去掉 callback 可以在 Window 菜单栏显示
	public static void Init(System.Action callback = null)
	{
		EditorWindowDemo.callback = callback;
		EditorWindowDemo window = (EditorWindowDemo)EditorWindow.GetWindow (typeof(EditorWindowDemo));
		window.Show ();
	}

	void OnGUI()
	{
		this.toolbarOption = GUILayout.Toolbar (this.toolbarOption, this.toolbarTexts);
		switch(this.toolbarOption)
		{
			case 0 :
					this.CreateTabOne();
				break;
			case 1 :
					this.CreateTabTwo();
				break;
			case 2 : 
					this.CreateTabThree();
				break;
			case 3 : 
					this.CreateTabFour();
				break;
		}
	}

	private void CreateTabOne()
	{
		GUILayout.Label ("Tab One Property:", EditorStyles.boldLabel);
		EditorGUILayout.BeginHorizontal ();
		GUILayout.Label ("Position Info: \t");
		this.xCheckbox = GUILayout.Toggle (this.xCheckbox, "X");
		this.yCheckbox = GUILayout.Toggle (this.yCheckbox, "Y");
		this.zCheckbox = GUILayout.Toggle (this.zCheckbox, "Z");
		EditorGUILayout.EndHorizontal ();
		
		EditorGUILayout.Space ();

		if(GUILayout.Button("Tab One Button"))
		{
			Debug.Log("checkStatus -> x : " + this.xCheckbox + ", y : " + this.yCheckbox + ", z : " + this.zCheckbox);
			if(EditorWindowDemo.callback != null)
			{
				EditorWindowDemo.callback("Tab One Button");
			}
		}
	}

	private void CreateTabTwo()
	{
		GUILayout.Label ("Tab Two Property:", EditorStyles.boldLabel);
		EditorGUILayout.BeginHorizontal ();
		this.itemName = EditorGUILayout.TextField ("Item Name:", this.itemName);
		EditorGUILayout.EndHorizontal ();
		
		EditorGUILayout.Space ();

		if(GUILayout.Button("Tab Two Button"))
		{
			Debug.Log("item name -> " + this.itemName);
			if(EditorWindowDemo.callback != null)
			{
				EditorWindowDemo.callback("Tab Two Button");
			}
		}
	}

	private void CreateTabThree()
	{
		GUILayout.Label ("Tab Three Property:", EditorStyles.boldLabel);
		EditorGUILayout.BeginHorizontal ();
		GUILayout.Label ("Transform Info: \t");
		this.itemObject = EditorGUILayout.ObjectField (this.itemObject, typeof(Transform)) as Transform;
		EditorGUILayout.EndHorizontal ();
		
		EditorGUILayout.Space ();

		if(GUILayout.Button("Tab Three Button"))
		{
			if(this.itemObject != null)
			{
				Debug.Log("transform name -> " + this.itemObject.name);
			}else
			{
				Debug.Log("transform name -> " + "null");
			}
			if(EditorWindowDemo.callback != null)
			{
				EditorWindowDemo.callback("Tab Three Button");
			}
		}
	}

	private void CreateTabFour()
	{
		GUILayout.Label ("Tab Four Property:", EditorStyles.boldLabel);
		EditorGUILayout.BeginHorizontal ();
		GUILayout.Label ("Color Info: \t");
		this.itemColor = EditorGUILayout.ColorField (this.itemColor);
		EditorGUILayout.EndHorizontal ();
		
		EditorGUILayout.Space ();

		if(GUILayout.Button("Tab Four Button"))
		{
			Debug.Log("color info -> " + this.itemColor.a + ":" + this.itemColor.r + ":" + this.itemColor.g + ":" + this.itemColor.b);
			if(EditorWindowDemo.callback != null)
			{
				EditorWindowDemo.callback("Tab Four Button");
			}
		}
	}
}


第四种:Editor。对某自定义组件进行观察的Inspector窗口,可以从它派生。效果如图:

与普通 Script 的区别如图:

代码如下:

using UnityEngine;
using System;

public class EditorComponent : MonoBehaviour 
{
	[Serializable]
	public class Data
	{
		public float floatData;
		public Vector3 vectorData;
		public Color colorData;
	}

	public Data data;
	public float floatData;
	public Color colorData;
	public Transform transformData;
}

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(EditorComponent))]
public class EditorDemo : Editor 
{
	private SerializedObject editorCompoent;
	private SerializedProperty data;
	private SerializedProperty floatData;
	private SerializedProperty colorData;
	private SerializedProperty transformData;
	
	void OnEnable() 
	{
		this.editorCompoent = new SerializedObject(target);
		this.data = this.editorCompoent.FindProperty("data");
		this.floatData = this.editorCompoent.FindProperty("floatData");
		this.colorData = this.editorCompoent.FindProperty("colorData");
		this.transformData = this.editorCompoent.FindProperty("transformData");
	}
	
	public override void OnInspectorGUI()
	{
		this.editorCompoent.Update ();

		EditorGUILayout.BeginHorizontal();
		GUILayout.Label ("Data");
		EditorGUILayout.PropertyField(this.data.FindPropertyRelative("floatData"), GUIContent.none);
		EditorGUILayout.PropertyField(this.data.FindPropertyRelative("vectorData"), GUIContent.none);
		EditorGUILayout.PropertyField(this.data.FindPropertyRelative("colorData"), GUIContent.none);
		EditorGUILayout.EndHorizontal();

		EditorGUILayout.PropertyField (this.floatData, new GUIContent("Float Data"));
		EditorGUILayout.PropertyField (this.colorData, new GUIContent("Color Data"));
		EditorGUILayout.PropertyField (this.transformData, new GUIContent("Transform Data"));

		if(GUILayout.Button("ScriptableObject Button"))
		{
			// 点击显示调用 MainMenuItemDemo 函数
			ScriptableObjectDemo.MainMenuItemDemo((string paramData)=>
			{
				Debug.Log("ScriptableObject 回调数据为:" + paramData);
			});
		}

		if(GUILayout.Button("ScriptableWizard Button"))
		{
			// 点击显示 ScriptableWizard 界面
			ScriptableWizardDemo.Init((string paramData)=>
			{
				Debug.Log("ScriptableWizard 回调数据为:" + paramData);
			});
		}

		if(GUILayout.Button("EditorWindow Button"))
		{
			// 点击显示 EditorWindow 界面
			EditorWindowDemo.Init((string paramData)=>
			{
				Debug.Log("EditorWindow 回调数据为:" + paramData);
			});
		}

		this.editorCompoent.ApplyModifiedProperties ();
	}
}


为了展示窗口之间的调用与回调,在 EditorDemo 中添加了三个按钮来弹出上面三种(ScriptableObject 没有界面)窗口,同时也在 EditorDemo 中处理了这三个窗口的回调函数。效果如图:






原文链接:http://blog.csdn.net/jjiss318/article/details/7435708

你可能感兴趣的:(Editor编辑器,编辑器)