Reputation: 26768
I am trying to implement edit-mode scripts in my Unity project. The idea is that a script can be attached to an object and as it's edited, attributes like scale/position/rotation can be seen updating.
Without writing an edit mode script, all this stuff is possible, but the changes are not visible until the play button is pressed. That's the difference here.
I'm using a variation of the script provided here to do this.
First of all I have a MonoBehavior script attached to my game object - it looks like so:
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);
}
}
Second I have a script in the Editor folder that calls this updateEditorState
method whenever a "Update" button is pressed:
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();
}
}
}
}
This works fine and I'm thankful for that, but this last chunk of code is pure boilerplate. I will need to have a nearly-identical one of these files for each script that I want to effect edit mode.
So I started on trying to make a "meta" editor script. The idea is that this script would have an array of slots that the developer can drag scripts into. Each script dragged here will get a CustomEditor class defined like the one shown above. Of course the classes being dragged here would each need to implement updateEditorState
but that's the only requirement of the protocol.
So if I make another editor script that looks like this:
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()
}
}
}
}
Then I can trigger the updateEditorState
function in the following:
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?
}
}
}
But as you can see I don't know how to dynamically generate the classes.
Upvotes: 0
Views: 808
Reputation: 1563
I don't think your approach will work purely dynamically. Unity compiles your code everytime you change something and come back to unity. After compiling it Unity uses Reflection to determine which editors are available.
You could theoretically create new source files which contain the editor code. I don't know though whether it will automagically reimport the scripts or you need to manually trigger the reimport.
For manually reimporting you can use a combination of AssetDatabase.Refresh()
and if that is not enough, select the script asset via the Selection
class and trigger the reimport menu entry using EditorApplication.ExecuteMenuItem
.
Upvotes: 1