Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Unity/C中动态创建CustomEditor类#_C#_Unity3d_Unity Components_Unity Editor - Fatal编程技术网

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

C# 在Unity/C中动态创建CustomEditor类#,c#,unity3d,unity-components,unity-editor,C#,Unity3d,Unity Components,Unity Editor,我正在尝试在我的Unity项目中实现编辑模式脚本。其思想是,可以将脚本附加到对象上,并且在对其进行编辑时,可以看到缩放/位置/旋转等属性在更新 无需编写编辑模式脚本,所有这些都是可能的,但只有按下播放按钮才能看到更改。这就是这里的区别 我正在使用提供的脚本的变体来实现这一点 首先,我有一个单行为脚本连接到我的游戏对象-看起来是这样的: using System.Collections; using System.Collections.Generic; using UnityEngine; [

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

无需编写编辑模式脚本,所有这些都是可能的,但只有按下播放按钮才能看到更改。这就是这里的区别

我正在使用提供的脚本的变体来实现这一点

首先,我有一个单行为脚本连接到我的游戏对象-看起来是这样的:

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);
    }
}
其次,我在编辑器文件夹中有一个脚本,每当按下“更新”按钮时,它就会调用这个
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();
            }
        }
    }
}
这很好用,我对此表示感谢,但最后一段代码是纯样板。我将需要有一个几乎相同的一个这些文件的每个脚本,我想影响编辑模式

所以我开始尝试制作一个“元”编辑器脚本。这个想法是,这个脚本将有一个插槽数组,开发人员可以将脚本拖到其中。在这里拖动的每个脚本将获得一个自定义编辑器类,如上图所示。当然,这里拖动的类都需要实现
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?
        }
    }
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
使用UnityEditor;
公共类EditModeScripts:MonoBehavior{
公共单行为[]脚本={};
public void updateEditorState(){
for(int i=0;i

但是正如您所看到的,我不知道如何动态生成类。

我认为您的方法不会完全动态地工作。每次您更改某些内容并返回Unity时,Unity都会编译您的代码。编译后,Unity使用反射来确定哪些编辑器可用

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

对于手动重新导入,您可以结合使用,如果这还不够,请通过类选择脚本资源,并使用触发重新导入菜单项