您的位置:首页 > 移动开发 > Unity3D

Unity3D之监听Hierachy、Project等视图结构变化的事件

2015-01-27 20:47 399 查看
以前就有人问我怎么监听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变化了。所以我觉得可以自己写一段代码来对比一下前后。 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: