OnGUI是Unity上一个时代的UI系统,而现在运行时的UI系统已经被UGUI取代,但是Editor的UI还是在用老的这一套GUI系统。比如unity编辑器里的所有窗口,布局,按钮,拖动条、滚动等等都是用GUI来写的。GUI提供了一套Event事件系统,虽然不能模拟它的事件(其实是可以发的 EditorWindow.SendEvent ),但是确可以进行拦截。
比如说:
1.限制Hierarchy视图的树状结构。(让某些对象不可随意移动层次结构)
2.限制Project里的资源不能任意拖动(限制美术只能把一些资源放在规定的文件夹下面)
3.限制GUI中按钮的点击
4.拖拽资源或者对象绑定的时候执行一些自己的代码 等等
把下面这段代码拷贝到你的工程中,你会发现你的Hierarchy视图还有Porject视图中的所有对象不能任意拖动了。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
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下的就说完了,我们再说说运行时的。如下图所示,我可以通过事件拦截的方法让这个按钮永远得不到点击的响应。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
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的事件。
- 本文固定链接: https://www.xuanyusong.com/archives/3889
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
UGUI是否和ONGUI一样呢?
UGUI好用一些,不过效率和NGUI一样都很差
多谢雨松大大回复开心O(∩_∩)O~~~最近要做一个人体动作识别的项目,使用的是OpenCV这个开源库(unity资源商店可以下载),能否让unity使用相关的C++接口,使用java接口效率太低了。。。
多谢雨松大大回复开心O(∩_∩)O~~~最近要做一个人体动作识别的项目,使用的是OpenCV这个开源库(unity资源商店可以下载),能否让unity使用相关的C 接口,使用java接口效率太低了。。。
看到这个我想到了不拦截GUI 拦截GUI后面的UI的点击事件,不过看起来好像是两套事件体系。。