最近我发现了一个更好的方法来监听Project视图变化,欢迎大家前来看看 Unity3D研究院之监听Project视图结构变化的事件
以前就有人问我怎么监听Hierarchy视图中创建或删除变化的事件,当时因为有别的事情就没研究这块。刚好最近有这一类的需求我就学习学习。网上发现了一个日本人写的文档,实现的原理很有意思,内容不错我就翻译一下。
原文:http://anchan828.hatenablog.jp/entry/2013/12/29/015306
请注意一定把这两个监听的脚本放在Editor文件夹下。
先是基类。
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
using
System
;
using
System
.
Collections
;
using
System
.
Reflection
;
using
UnityEditor
;
using
UnityEngine
;
[
InitializeOnLoad
]
public
class
EditorMonoBehaviour
{
static
EditorMonoBehaviour
(
)
{
var
type
=
Types
.
GetType
(
"UnityEditor.EditorAssemblies"
,
"UnityEditor.dll"
)
;
var
method
=
type
.
GetMethod
(
"SubclassesOf"
,
BindingFlags
.
Static
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
,
null
,
new
Type
[
]
{
typeof
(
Type
)
}
,
null
)
;
var
e
=
method
.
Invoke
(
null
,
new
object
[
]
{
typeof
(
EditorMonoBehaviour
)
}
)
as
IEnumerable
;
foreach
(
Type
editorMonoBehaviourClass
in
e
)
{
method
=
editorMonoBehaviourClass
.
BaseType
.
GetMethod
(
"OnEditorMonoBehaviour"
,
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
)
;
if
(
method
!=
null
)
{
method
.
Invoke
(
System
.
Activator
.
CreateInstance
(
editorMonoBehaviourClass
)
,
new
object
[
0
]
)
;
}
}
}
private
void
OnEditorMonoBehaviour
(
)
{
EditorApplication
.
update
+=
Update
;
EditorApplication
.
hierarchyWindowChanged
+=
OnHierarchyWindowChanged
;
EditorApplication
.
hierarchyWindowItemOnGUI
+=
HierarchyWindowItemOnGUI
;
EditorApplication
.
projectWindowChanged
+=
OnProjectWindowChanged
;
EditorApplication
.
projectWindowItemOnGUI
+=
ProjectWindowItemOnGUI
;
EditorApplication
.
modifierKeysChanged
+=
OnModifierKeysChanged
;
// globalEventHandler
EditorApplication
.
CallbackFunction
function
=
(
)
=
>
OnGlobalEventHandler
(
Event
.
current
)
;
FieldInfo
info
=
typeof
(
EditorApplication
)
.
GetField
(
"globalEventHandler"
,
BindingFlags
.
Static
|
BindingFlags
.
Instance
|
BindingFlags
.
NonPublic
)
;
EditorApplication
.
CallbackFunction
functions
=
(
EditorApplication
.
CallbackFunction
)
info
.
GetValue
(
null
)
;
functions
+=
function
;
info
.
SetValue
(
null
,
(
object
)
functions
)
;
EditorApplication
.
searchChanged
+=
OnSearchChanged
;
EditorApplication
.
playmodeStateChanged
+=
(
)
=
>
{
if
(
EditorApplication
.
isPaused
)
{
OnPlaymodeStateChanged
(
PlayModeState
.
Paused
)
;
}
if
(
EditorApplication
.
isPlaying
)
{
OnPlaymodeStateChanged
(
PlayModeState
.
Playing
)
;
}
if
(
EditorApplication
.
isPlayingOrWillChangePlaymode
)
{
OnPlaymodeStateChanged
(
PlayModeState
.
PlayingOrWillChangePlaymode
)
;
}
}
;
}
public
virtual
void
Update
(
)
{
}
public
virtual
void
OnHierarchyWindowChanged
(
)
{
}
public
virtual
void
HierarchyWindowItemOnGUI
(
int
instanceID
,
Rect
selectionRect
)
{
}
public
virtual
void
OnProjectWindowChanged
(
)
{
}
public
virtual
void
ProjectWindowItemOnGUI
(
string
guid
,
Rect
selectionRect
)
{
}
public
virtual
void
OnModifierKeysChanged
(
)
{
}
public
virtual
void
OnGlobalEventHandler
(
Event
e
)
{
}
public
virtual
void
OnSearchChanged
(
)
{
}
public
virtual
void
OnPlaymodeStateChanged
(
PlayModeState
playModeState
)
{
}
public
enum
PlayModeState
{
Playing
,
Paused
,
Stop
,
PlayingOrWillChangePlaymode
}
}
|
接着是继承类,所有监听的事件在这里完成,两个类都不用实例化也不用NEW直接就可以监听。
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
|
using
UnityEditor
;
using
UnityEngine
;
public
class
NewBehaviourScript
:
EditorMonoBehaviour
{
public
override
void
Update
(
)
{
//Debug.Log ("每一帧回调一次");
}
public
override
void
OnPlaymodeStateChanged
(
PlayModeState
playModeState
)
{
//Debug.Log ("游戏运行模式发生改变, 点击 运行游戏 或者暂停游戏或者 帧运行游戏 按钮时触发: " + playModeState);
}
public
override
void
OnGlobalEventHandler
(
Event
e
)
{
//Debug.Log ("全局事件回调: " + e);
}
public
override
void
HierarchyWindowItemOnGUI
(
int
instanceID
,
Rect
selectionRect
)
{
// Debug.Log (string.Format ("{0} : {1} - {2}", EditorUtility.InstanceIDToObject (instanceID), instanceID, selectionRect));
}
public
override
void
OnHierarchyWindowChanged
(
)
{
Debug
.
Log
(
"层次视图发生变化"
)
;
}
public
override
void
OnModifierKeysChanged
(
)
{
// Debug.Log ("当触发键盘事件");
}
public
override
void
OnProjectWindowChanged
(
)
{
// Debug.Log ("当资源视图发生变化");
}
public
override
void
ProjectWindowItemOnGUI
(
string
guid
,
Rect
selectionRect
)
{
//根据GUID得到资源的准确路径
//Debug.Log (string.Format ("{0} : {1} - {2}", AssetDatabase.GUIDToAssetPath (guid), guid, selectionRect));
}
}
|
思考:因为在这里我们只能得到它变化的事件,但是我们不知道哪个GameObject变化了。所以我觉得可以自己写一段代码来对比一下前后