我正在尝试在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?
}
}
}
但是你可以看到我不知道如何动态生成类。
答案 0 :(得分:1)
我不认为你的方法会纯粹动态地运作。每当你改变某些东西并回归统一时,Unity就会编译你的代码。在编译之后,Unity使用Reflection来确定哪些编辑器可用。
理论上,您可以创建包含编辑器代码的新源文件。我不知道它是否会自动重新导入脚本,或者您需要手动触发重新导入。
对于手动重新导入,您可以使用AssetDatabase.Refresh()
的组合,如果这还不够,请通过Selection
类选择脚本资源,然后使用EditorApplication.ExecuteMenuItem
触发重新导入菜单项。< / p>