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

    }
}
时间: 2024-10-09 08:11:09

【Unity3D】用继承EditorUpdater类来实现Editor模式下的后台处理的相关文章

在Editor模式下编辑贝塞尔曲线

贝塞尔曲线的原理以及具体实现方式在网上随处可见,这里不再赘述.实际上,在Unity的Editor模式下,系统已经提供了现成的接口,只需要简单的几行代码,便能实现可自由拖曳的贝塞尔曲线. 首先,创建一个Bezier.cs文件,具体代码如下: //将代码添加至任意GameObject即可 using UnityEngine; using System.Collections; public class Bezier : MonoBehaviour { //起始于startPosition,走向于st

Unity3D Editor模式下批量修改prefab

最经遇到一个需要批量修改已经做好的prefab的问题,查了一些资料最终实现了但是还是不够完美,通过学习也发现unity的编辑器功能还是非常强大的.废话不多说直接上代码: 1 [ExecuteInEditMode] 2 [MenuItem("Tools/RecordPoint Add Flame")] 3 private static void RecordPointAddFlame() 4 { 5 GameObject twoSphere = AssetDatabase.LoadAss

在editor模式下遍历unity3d builtsetting中的场景

foreach (UnityEditor.EditorBuildSettingsScene S in UnityEditor.EditorBuildSettings.scenes) { //在built setting中是否已经开启 if(S.enabled) { //得到场景的名称 string name = S.path; //打开这个场景 EditorApplication.OpenScene(name); //遍历场景中的GameObject foreach (GameObject ob

二、Unity Editor模式下,操作选中对象

使用Unity提供的工具类 UnityEditor.Selection public static GameObject activeGameObject public static UnityEngine.Object activeObject 原文地址:https://www.cnblogs.com/hjshen/p/10219266.html

sizeof 和类继承 虚继承 求类大小

代码: #include <iostream> using namespace std; /* class a{ float k; // 4字节 virtual void foo(){} //有一个4字节的指针指向自己的虚函数表 }; class b : virtual public a{ virtual void f(){} }; 有这样的一个指针vptr_b_a,这个指针叫虚类指针,也是四个字节:还要包括类a的字节数,所以类b的字节数就求出来了. 运行结果: 8 16 */ /* clas

多线程_创建线程_继承Thread类

public class ThreadDemo {   public static void main(String[] args){         Demo d = new Demo();   d.start();      for(int i = 0;i < 100;i++){      System.out.println("MainThread" + i);   }   } } class Demo extends Thread {   public void run(

面向对象【day07】:类的属性-继承-经典类

本节内容 类的公有属性 析构函数 类的继承 新式类和经典类 一.类的公有属性 一.概述 前面我们讲了类的私有属性,现在我们来说说类的公有属性,这边很容易被人弄混淆,有人觉的,在__init__()构造方法中,除了私有属性,其他的都是公有属性了,其实这是一个错误的结论,并不是定义在__init__()初始化方法中的属性是公有属性(除私有属性),那什么是公有属性呢?揭起了大家的好奇心. 定义:指的是所属这个类的所有对象,都可以访问的属性,叫做公有属性. 二.公有属性 2.1 定义 说明:在类中直接定

19._7泛型继承之泛型类继承普通类

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _19._7泛型继承之泛型类继承普通类 { abstract class genClass<T> { protected T field; public virtual T property { get { return field; } } p

Java通过继承thread类与实现Runnable接口实现多线程的区别

Java中线程的创建有两种方式: 1.  通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中 2.  通过实现Runnable接口,实例化Thread类 一.通过继承Thread类实现多线程 class MyThread extends Thread{ String name = null; int ticket = 0; public MyThread(String name){ this.name = name; } public synchronized v