OnGUI是Unity上一個時代的UI系統,而現在運行時的UI系統已經被UGUI取代,但是Editor的UI還是在用老的這一套GUI系統。比如unity編輯器里的所有窗口,布局,按鈕,拖動條、滾動等等都是用GUI來寫的。GUI提供了一套Event事件系統,雖然不能模擬它的事件(其實是可以發的 EditorWindow.SendEvent ),但是確可以進行攔截。
比如說:
1.限制Hierarchy視圖的樹狀結構。(讓某些對象不可隨意移動層次結構)
2.限制Project里的資源不能任意拖動(限制美術只能把一些資源放在規定的文件夾下面)
3.限制GUI中按鈕的點擊
4.拖拽資源或者對象綁定的時候執行一些自己的代碼 等等
把下面這段代碼拷貝到你的工程中,你會發現你的Hierarchy視圖還有Porject視圖中的所有對象不能任意拖動了。。
using UnityEngine;
using UnityEditor;
using System.Collections;
using System;
public class MyEditor
{
[InitializeOnLoadMethod]
static void Start ()
{
Action OnEvent = delegate {
Event e = Event.current;
switch (e.type) {
// case EventType.mouseDown:
// Debug.Log ("mousedown");
// e.Use ();
// break;
// case EventType.mouseUp:
// Debug.Log ("mouseup");
// e.Use ();
// break;
// case EventType.MouseMove:
// Debug.Log ("move");
// e.Use ();
// break;
case EventType.DragPerform:
Debug.Log ("DragPerform");
e.Use ();
break;
case EventType.DragUpdated:
Debug.Log ("DragUpdated");
e.Use ();
break;
case EventType.DragExited:
Debug.Log ("DragExited");
e.Use ();
break;
}
};
EditorApplication.hierarchyWindowItemOnGUI = delegate(int instanceID, Rect selectionRect) {
OnEvent();
};
EditorApplication.projectWindowItemOnGUI = delegate(string guid, Rect selectionRect) {
OnEvent();
};
}
}
首先獲取事件必須在OnGUI中完成,Editor下也可以在類似的XXXOnGUI中完成。
Event.current就是獲取當前的事件,所有的事件都是由我們自己手動操作鼠標或者鍵盤產生的。比如 按下、抬起、移動、拖拽、右鍵、滾動、粘貼、復制、選擇。全選 等 事件、詳細的事件類型在這里。 http://docs.unity3d.com/ScriptReference/EventType.html
代碼中只需要去判斷當前事件的類型,假如不想讓這個事件滲透執行下去,那么就調用e.Use() 方法。這個方法的意思就是把這個事件刪除了,不讓后面的代碼能監聽到它。
剩下的就是配合Selection.objects和 DragAndDrop.objectReferences 以及Input.mousePostion 一類的方法 來判斷當前操作的對象,通過邏輯來靈活的判斷是否要執行事件。或者是執行事件的同時在執行一些自己的代碼。。
OK Editor下的就說完了,我們再說說運行時的。如下圖所示,我可以通過事件攔截的方法讓這個按鈕永遠得不到點擊的響應。
代碼是這樣的
void OnGUI()
{
Event e = Event.current;
if (e != null) {
switch (e.type) {
case EventType.mouseDown:
e.Use ();
break;
}
}
if (GUILayout.Button ("1")) {
Debug.Log ("cilick");
}
}
總體來說我覺得Editor下還是很有必要監聽事件類型的,因為想做一個好用的編輯器真的離不開這些。 最后歡迎大家在下面給我留言,我們一起討論GUI的事件。