EditorWindow类的OnGUI函数只会在窗口焦点处于Editor窗口上的时候才会运行。如果希望焦点不在Editor窗口上的时候,它也能实时更新,可以实现以下方法:
OnDestroy | OnDestroy is called when the EditorWindow is closed. |
OnFocus | Called when the window gets keyboard focus. |
OnGUI | Implement your own editor GUI here. |
OnHierarchyChange | Called whenever the scene hierarchy has changed. |
OnInspectorUpdate | OnInspectorUpdate is called at 10 frames per second to give the inspector a chance to update. |
OnLostFocus | Called when the window loses keyboard focus. |
OnProjectChange | Called whenever the project has changed. |
OnSelectionChange | Called whenever the selection has changed. |
Update | Called multiple times per second on all visible windows. |
但是,如果Editor窗口被贴到大窗口上后,选择和它平级的窗口,从而隐藏了Editor窗口,这样OnGUI函数仍然无法调用。所以,我们为了实现更有效的后台处理,可以采用继承一个自己写的EditorUpdate类的方式。
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; 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); function += 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); } }; Start (); } public virtual void Start() {} 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 } }
然后在另一个脚本中继承这个类,并重载Start和Update等方法,在这些方法中实现后台逻辑,就可以后台更新了。
using UnityEngine; using System.Collections; public class UpdaterTest :EditorMonoBehaviour { public override void Update () { } }
时间: 2024-10-09 08:11:09