Unity監聽Hierachy檢視變化
阿新 • • 發佈:2019-01-08
經過一番百度我找到了兩種方法。
一、是EditorWindow.OnHierarchyChang這種要建立一個視窗,而且這個視窗關閉了就失效了,不管那麼多來看實現程式碼:
該指令碼要放在Editor資料夾下。using UnityEngine; using System.Collections; using UnityEditor; public class HierachyChange : EditorWindow { [MenuItem("Tools/HierachyChangeWindow")] static void AddWindow() { Rect wr = new Rect(0, 0, 500, 500); HierachyChange window = (HierachyChange)EditorWindow.GetWindowWithRect(typeof(HierachyChange), wr, true, "widow name"); window.Show(); } void OnHierarchyChange() { Debug.Log("當Hierarchy檢視中的任何物件發生改變時呼叫一次,改變後儲存當前場景還會呼叫一次"); } }
二、是我在雨鬆MOMO的一篇文章裡看到的,這裡我也把他的程式碼貼出來,有興趣的可以去他的原文http://www.xuanyusong.com/archives/3053 註明:以下程式碼出自 雨鬆MOMO的Unity3D研究院之監聽Hierachy、Project等檢視結構變化的事件這篇文章:
下面是子類他實現了上面的虛擬函式。//這個是基類 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 } }
把這兩個類放在Editor資料夾裡就行了。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)); } }