unity3d Unity,同一类型的多个自定义编辑器

pdkcd3nj  于 2022-12-30  发布在  其他
关注(0)|答案(2)|浏览(205)

我正在Unity 5.6中制作一个基于插件的C#应用程序,其中有些插件可能会安装,有些则不会。
在我的插件Plugin1中,我有一个组件Plugin1.Component1。在同一个项目中,我为它实现了一个自定义编辑器,称为Plugin1.Component1Editor,即[CustomEditor(typeof(Plugin1.Component1))]。当安装Plugin1时,Component1可用,并使用自定义编辑器呈现。
我的插件Plugin2依赖于Plugin1。根据它的组件Plugin2.Component2中的设置,它想改变Plugin1.Component1的自定义编辑器。
我在Plugin2中实现了一个新的自定义编辑器,叫做Plugin2.Component1Editor,也是[CustomEditor(typeof(Plugin1.Component1))],它继承自UnityEditor.Editor,而不是Plugin1.Component1Editor,因为后者会导致在Plugin1.Component1Editor中找不到序列化属性的问题。
Plugin2.Component1Editor在编译时不会与Plugin1.Component1Editor冲突,因为它有自己的命名空间。但Unity检查器中实际发生了什么?
测试时的行为是所需的行为:除非没有安装Plugin2,否则Plugin2.Component1Editor会渲染检查器。但是为什么呢?除非我知道为什么,否则我不想相信它会一直这样做。
谢谢大家!
编辑:我错了,它没有渲染Plugin2.Component1Editor,它是默认的Unity编辑器在运行。我的两个自定义编辑器都没有使用。我如何指定我想使用哪个?

qybjjes1

qybjjes11#

看来,解决办法确实是继承。
我将序列化属性设置为由Plugin1.Component1Editor处理,并保护它们的检索而不是私有的,然后Plugin2.Component1Editor继承自Plugin1.Component1Editor而不是UnityEditor.Editor,然后Plugin2.Component1Editor成为呈现属性,并根据需要调用Plugin1.Component1Editor
该解决方案的主要部分是我在Plugin1.Component1Editor中进行了OnEnable调用,它检索序列化属性protected,以便我可以通过base.OnEnable()Plugin2.Component1Editor调用它。

baubqpgj

baubqpgj2#

对于遇到这个问题的人来说,OP的解决方案只有在你有Plugin1和Plugin2的情况下才有效(至少对我来说),如果你有Plugin3,最后一个插件将不会作为自定义编辑器加载。
我决定使用一个“编辑器中心”,一个Component1的自定义编辑器,它使用System.Reflection查找ICustomEditor接口实现,而且Unity有一个很好的类,如TypeCache,它可以让您加载类

public interface ICustomEditor
    {
        EditorType Type { get; }
        void OnEnable(SerializedObject target);
        void OnInspectorGUI(SerializedObject target);
    }

我决定在主编辑器之前或之后使用EditorType.BeforeEditorType.After来呈现定制特性。

protected virtual void OnEnable()
    {
        CollectEditors();
        OnEnableEditors();
    }

    public override void OnInspectorGUI()
    {
        OnInspectorGUIBefore();
        base.OnInspectorGUI();
        OnInspectorGUIAfter();
    }

    private void CollectEditors()
    {
        var types = TypeCache.GetTypesDerivedFrom(typeof(ICustomEditor));

        var list = new List<ICustomEditor>();

        foreach (var e in types)
        {
            var editor = (ICustomEditor)Activator.CreateInstance(e);
            list.Add(editor);
        }

        m_beforeEditors = list
            .Where(t => t.Type == EditorType.Before)
            .ToArray();

        m_afterEditors = list
            .Where(t => t.Type == EditorType.After)
            .ToArray();
    }

相关问题