【Unity3D】用繼承EditorUpdater類來實現Editor模式下的后台處理


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 ()
    {
        
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM