在Unity / C中动态创建CustomEditor类#

时间:2017-09-20 19:13:00

标签: c# unity3d unity-components unity-editor

我正在尝试在Unity项目中实现编辑模式脚本。我们的想法是可以将脚本附加到对象上,并且在编辑时,可以看到比例/位置/旋转等属性更新。

如果不编写编辑模式脚本,可以使用所有这些内容,但在按下播放按钮之前,更改不可见。这就是区别。

我正在使用here提供的脚本的变体来执行此操作。

首先,我将一个MonoBehavior脚本附加到我的游戏对象 - 它看起来像这样:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteInEditMode]
public class FlippersEditMode : MonoBehaviour {
    public float extraScale = 1f;
    public void updateEditorState() {
        transform.localScale = (Vector3.up * extraScale);
    }
}

第二,我在Editor文件夹中有一个脚本,只要按下“Update”按钮就调用这个updateEditorState方法:

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(FlippersEditMode))]
public class FlipperEditModeMeta: Editor {
    public override void OnInspectorGUI() {
        base.OnInspectorGUI();
        if (GUILayout.Button("Update")) {
            if (target.GetType() == typeof(FlippersEditMode)) {
                FlippersEditMode flippers = (FlippersEditMode)target;
                flippers.updateEditorState();
            }
        }
    }
}

这很好用,我很感激,但最后一块代码是纯粹的样板。对于我想要实现编辑模式的每个脚本,我需要有一个几乎完全相同的文件。

所以我开始尝试制作一个“元”编辑器脚本。这个想法是这个脚本将有一个开发人员可以拖动脚本的插槽数组。拖动到此处的每个脚本都将获得一个如上所示定义的CustomEditor类。当然,在这里拖动的类每个都需要实现updateEditorState,但这是协议的唯一要求。

因此,如果我创建另一个看起来像这样的编辑器脚本:

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(EditModeScripts))]
public class EditModeScriptsMeta : Editor {
    public override void OnInspectorGUI() {
        base.OnInspectorGUI();
        if (GUILayout.Button("Update")) {
            if (target.GetType() == typeof(EditModeScripts)) {
                EditModeScripts edit_mode_scripts = (EditModeScripts)target;
                edit_mode_scripts.updateEditorState()
            }
        }
    }
}

然后我可以触发以下updateEditorState功能:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class EditModeScripts : MonoBehaviour {

    public MonoBehaviour[] scripts = {};

    public void updateEditorState () {
        for (int i = 0; i < scripts.Length; i++) {
            MonoBehaviour script = scripts[i];
            // How to generate an editor class here for each script?
        }
    }
}

但是你可以看到我不知道如何动态生成类。

1 个答案:

答案 0 :(得分:1)

我不认为你的方法会纯粹动态地运作。每当你改变某些东西并回归统一时,Unity就会编译你的代码。在编译之后,Unity使用Reflection来确定哪些编辑器可用。

理论上,您可以创建包含编辑器代码的新源文件。我不知道它是否会自动重新导入脚本,或者您需要手动触发重新导入。

对于手动重新导入,您可以使用AssetDatabase.Refresh()的组合,如果这还不够,请通过Selection类选择脚本资源,然后使用EditorApplication.ExecuteMenuItem触发重新导入菜单项。< / p>