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
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
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的事件。

Unity3D研究院编辑器之Editor的GUI的事件拦截的更多相关文章

  1. [Unity] Unity3D研究院编辑器之自定义默认资源的Inspector面板

    比如编辑模式下对场景或者特定文件夹有一些操作可以在这个面板里来完成.. 代码如下. using UnityEngine; using System.Collections; using UnityEd ...

  2. Unity3D研究院编辑器之自定义默认资源的Inspector面板

    比如编辑模式下对场景或者特定文件夹有一些操作可以在这个面板里来完成. 代码如下: using System.Collections; using System.Collections.Generic; ...

  3. [Unity] Unity3D研究院编辑器之独立Inspector属性

    本文转自: http://www.xuanyusong.com/archives/3680雨松MOMO Unity提供了强大的Editor功能, 我们可以很轻易的在EditorGUI中绘制任意的属性. ...

  4. Unity3D研究院编辑器之脚本设置ToolBar

    Unity版本5.3.2 如下图所示,ToolBar就是Unity顶部的那一横条.这里的所有按钮一般情况下都得我们手动的用鼠标去点击.这篇文章我们说说如果自动操作它们 1.自动点击左边四个按钮 (拖动 ...

  5. Unity3D研究院编辑器之不影响原有布局拓展Inspector

    今天无意间发现了一篇好文章,也让我解决了一个很久都没解决的难题.问题是这样的,假如我想去拓展Unity自带的inspector但是并不想影响原有布局. 比如下面这段代码:     1 2 3 4 5 ...

  6. Unity3D研究院编辑器之脚本获取资源内存和硬盘大小

    内存 使用Profiler可以查看某个资源的内存占用情况,但是必须启动游戏,并且待查看的资源已经载入游戏中.我希望的是不启动游戏,也能看到它的内存好做统计. 硬盘 由于unity中的资源压缩格式记录在 ...

  7. Unity3D研究院编辑器之脚本设置ToolBar及脚本设置顶视图

    Unity版本5.3.2 如下图所示,ToolBar就是Unity顶部的那一横条.这里的所有按钮一般情况下都得我们手动的用鼠标去点击.这篇文章我们说说如果自动操作它们 1.自动点击左边四个按钮 (拖动 ...

  8. 《转》Unity3D研究院编辑器之创建Lua脚本模板

    Unity里能创建 c#脚本模板,但是如果我想创建Lua脚本模板怎么办呢?拓展一下编辑器吧. 设置一下Lua脚本的模板地址 :  Assets/Editor/Lua/Template/lua.lua ...

  9. Unity3D研究院编辑器之不实例化Prefab获取删除更新组件(十五)

    http://www.xuanyusong.com/archives/3727 感谢楼下的牛逼回复更正一下,我表示我也是才知道.. 其实不需要实例化也能查找,你依然直接用GetComponentsIn ...

随机推荐

  1. C#线程状态简析

    在C# 语言世界中,当我们创建一个新的子线程,该线程状态为unstarted, 子线程开始之后,子线程状态为Running,IsAlive 为true: 线程响应 Thread.Start 并开始运行 ...

  2. 关于resolve非泛型方法不能与类型实参一起使用

    今天mvc新建三层时,写到bll层中一直报下面的错误,检查了几遍赶脚并没有什么错.最后发现缺少一些引用. 如下面的图,少添加了下面的两个引用.Unity是微软模式与实践团队开发的一个轻量级.可扩展的依 ...

  3. 2016 - 1 -19 初探NSOperation

    一:简介 1.NSOperation的作用: 配合NSOperation与NSOperationQueue也可以实现多线程. 2.NSOperation与NSOperationQueue实现多线程的步 ...

  4. python中的函数调用绑定,静态方法和类方法

    在C++的类中,有两种函数:普通成员函数和静态成员函数,差别是成员函数通过类实例调用,而静态成员函数通过类名调用.本质上,成员函数在调用的时候会默认把this指针作为第一个参数传入,而静态成员函数不需 ...

  5. 一、XML语法

    xml声明xml指令:<? ?>xml编码与乱码xml元素(标签)CDATA区空格与换行会被认为是标签的内容xml-stylesheet指令解析xml内容 <?xml version ...

  6. C# DataContract DataMember

    Windows Communication Foundation (WCF) uses a serialization engine called the Data Contract Serializ ...

  7. Java可变参数/可变长参数

    Java可变参数/可变长参数 传递的参数不确定长度,是变长的参数,例如小例子: package demo; public class Demo { public static int sum(int ...

  8. Request的参数信息

    Request.ServerVariables["Url"] 返回服务器地址 Request.ServerVariables["Path_Info"] 客户端提 ...

  9. [转]Table-Driven and Data Driven Programming

    What is Table-Driven and Data-Driven Programming? Data/Table-Driven programming is the technique of ...

  10. exit(-1)或者return(-1)为什么shell得到的退出码是255?

    写一段hello world: // filename: main.c #include <stdio.h> int main(void) { printf("hello wol ...