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

以前就有人问我怎么监听Hierarchy视图中创建或删除变化的事件,当时因为有别的事情就没研究这块。刚好最近有这一类的需求我就学习学习。网上发现了一个日本人写的文档,实现的原理很有意思,内容不错我就翻译一下。


请注意一定把这两个监听的脚本放在Editor文件夹下。


先是基类。


  1. using System;
  2. using System.Collections;
  3. using System.Reflection;
  4. using UnityEditor;
  5. using UnityEngine;

  6. [InitializeOnLoad]
  7. public class EditorMonoBehaviour
  8. {
  9.     static EditorMonoBehaviour ()
  10.     {
  11.         var type = Types.GetType ("UnityEditor.EditorAssemblies", "UnityEditor.dll");
  12.         var method = type.GetMethod ("SubclassesOf", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[]{ typeof(Type) }, null); 
  13.         var e = method.Invoke (null, new object[]{ typeof(EditorMonoBehaviour) }) as IEnumerable;
  14.         foreach (Type editorMonoBehaviourClass in e) {
  15.             method = editorMonoBehaviourClass.BaseType.GetMethod ("OnEditorMonoBehaviour", BindingFlags.NonPublic | BindingFlags.Instance);
  16.             if (method != null) {
  17.                 method.Invoke (System.Activator.CreateInstance (editorMonoBehaviourClass), new object[0]);
  18.             }
  19.         }
  20.     }

  21.     private void OnEditorMonoBehaviour ()
  22.     {

  23.         EditorApplication.update += Update;
  24.         EditorApplication.hierarchyWindowChanged += OnHierarchyWindowChanged;
  25.         EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
  26.         EditorApplication.projectWindowChanged += OnProjectWindowChanged;
  27.         EditorApplication.projectWindowItemOnGUI += ProjectWindowItemOnGUI;
  28.         EditorApplication.modifierKeysChanged += OnModifierKeysChanged;


  29.         // globalEventHandler
  30.         EditorApplication.CallbackFunction function = () => OnGlobalEventHandler (Event.current);
  31.         FieldInfo info = typeof(EditorApplication).GetField ("globalEventHandler", BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);
  32.         EditorApplication.CallbackFunction functions = (EditorApplication.CallbackFunction)info.GetValue (null);
  33.         functions += function;  
  34.         info.SetValue (null, (object)functions);


  35.         EditorApplication.searchChanged += OnSearchChanged;

  36.         EditorApplication.playmodeStateChanged += () => {
  37.             if (EditorApplication.isPaused) {
  38.                 OnPlaymodeStateChanged (PlayModeState.Paused);
  39.             }
  40.             if (EditorApplication.isPlaying) {
  41.                 OnPlaymodeStateChanged (PlayModeState.Playing);
  42.             }
  43.             if (EditorApplication.isPlayingOrWillChangePlaymode) {
  44.                 OnPlaymodeStateChanged (PlayModeState.PlayingOrWillChangePlaymode);
  45.             }
  46.         };

  47.     }

  48.     public virtual void Update ()
  49.     {
  50.                         
  51.     }

  52.     public virtual void OnHierarchyWindowChanged ()
  53.     {

  54.     }

  55.     public virtual void HierarchyWindowItemOnGUI (int instanceID, Rect selectionRect)
  56.     {

  57.     }

  58.     public virtual void OnProjectWindowChanged ()
  59.     {

  60.     }

  61.     public virtual void ProjectWindowItemOnGUI (string guid, Rect selectionRect)
  62.     {

  63.     }

  64.     public virtual void OnModifierKeysChanged ()
  65.     {

  66.     }

  67.     public virtual void OnGlobalEventHandler (Event e)
  68.     {

  69.     }

  70.     public virtual void OnSearchChanged ()
  71.     {
  72.     }

  73.     public virtual void OnPlaymodeStateChanged (PlayModeState playModeState)
  74.     {

  75.     }

  76.     public enum PlayModeState
  77.     {
  78.         Playing,
  79.         Paused,
  80.         Stop,
  81.         PlayingOrWillChangePlaymode
  82.     }
  83. }
复制代码


接着是继承类,所有监听的事件在这里完成,两个类都不用实例化也不用NEW直接就可以监听。

  1. using UnityEditor;
  2. using UnityEngine;

  3. public class NewBehaviourScript : EditorMonoBehaviour
  4. {
  5.         public override void Update ()
  6.         {
  7.                 //Debug.Log ("每一帧回调一次");
  8.         }
  9.         
  10.         public override void OnPlaymodeStateChanged (PlayModeState playModeState)
  11.         {
  12.                 //Debug.Log ("游戏运行模式发生改变, 点击 运行游戏 或者暂停游戏或者 帧运行游戏 按钮时触发: " + playModeState);
  13.         }
  14.         
  15.         public override void OnGlobalEventHandler (Event e)
  16.         {
  17.                 //Debug.Log ("全局事件回调: " + e);
  18.         }

  19.         public override void HierarchyWindowItemOnGUI (int instanceID, Rect selectionRect)
  20.         {
  21.                 //        Debug.Log (string.Format ("{0} : {1} - {2}", EditorUtility.InstanceIDToObject (instanceID), instanceID, selectionRect));
  22.         }
  23.         
  24.         public override void OnHierarchyWindowChanged ()
  25.         {
  26.                 Debug.Log ("层次视图发生变化");
  27.         }
  28.         
  29.         public override void OnModifierKeysChanged ()
  30.         {
  31.                 //        Debug.Log ("当触发键盘事件");
  32.         }
  33.         
  34.         public override void OnProjectWindowChanged ()
  35.         {
  36.                 //        Debug.Log ("当资源视图发生变化");
  37.         }
  38.         
  39.         public override void ProjectWindowItemOnGUI (string guid, Rect selectionRect)
  40.         {
  41.                 //根据GUID得到资源的准确路径
  42.                 //Debug.Log (string.Format ("{0} : {1} - {2}", AssetDatabase.GUIDToAssetPath (guid), guid, selectionRect));
  43.         }
  44. }
复制代码
      
      思考:因为在这里我们只能得到它变化的事件,但是我们不知道哪个GameObject变化了。所以我觉得可以自己写一段代码来对比一下前后。 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值