以前就有人问我怎么监听Hierarchy视图中创建或删除变化的事件,当时因为有别的事情就没研究这块。刚好最近有这一类的需求我就学习学习。网上发现了一个日本人写的文档,实现的原理很有意思,内容不错我就翻译一下。
请注意一定把这两个监听的脚本放在Editor文件夹下。
先是基类。
- 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直接就可以监听。
- 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变化了。所以我觉得可以自己写一段代码来对比一下前后。