Hi,
I made a script with its custom editor.
This is how I scripted it:
[CustomEditor(typeof(SceneEvent), true)]
public class SceneEventEditor : Editor
{
...
SceneEvent e;
void OnSceneGUI() {
Event current = Event.current;
...
public override void OnInspectorGUI() {
if (e == null) {
e = (SceneEvent)target;
}
...
To make the editor notice I did some changes, I’m calling these two functions every time one of the fields gets modified:
This was necessary to save my edits for SceneEvent components. It works totally fine when the object is only inside a scene, but unfortunately doesn’t work as soon as the SceneEvent component is in a Prefab… Even if I put the Prefab in the scene, modify and save, all the changes still gets lost.
I’ve noticed that if I enable “Debug” mode on the inspector (and so all of the parameters are shown as though as it had no custom editor) the changes does get saved. Currently it’s the only way for me to edit these components inside a prefab…
Is there any other action I need to accomplish to make it work? Does any of you had a similar issue?
You shouldn’t have to mark a scene dirty to persist changes to serialised data on components. You should only have to either record an undo instance, or mark it dirty with UnityEditor.EditorUtility.SetDirty().,
Though generally doing so means your custom inspector isn’t correctly modifying data via serialised properties, which should automatically handle dirtying. Generally you should avoid directly modifying the data for the target for individual fields and modify that through serialised properties.
Maybe you post more of the code of both the component and the custom inspector?
Assuming you write this to provide in-scene tooling, it’s best to use the corresponding system for that: EditorTool.
This is what the Transform, Rotate, etc. handles use that you can drag around or dock in the scene view. The EditorToolContext lets you enable your custom tool based on the selection, eg make it only appear if an object with YourSceneComponent is selected (or always show it, also an option).
For scene objects, Undo.RecrodObject is enough, it will automatically set the containing scene as dirty, calling EditorSceneManager.MarkAllScenesDirty() shouldn’t be necessary and potentially marks unrelated scenes dirty as well.
The Undo documentation unfortunately doesn’t mention it, but for assets, Undo.RecordObject isn’t enough, you also need to call EditorUtility.SetDirty on the asset:
In the case of ScriptableObject, call both SetDirty and Undo.RecordObject, if you want to register the change and support undo.
Finally, when working prefabs, the documentation of Undo.RecordObject points out:
Oh, I didn’t know about EditorTool. If I didn’t already wrote 2200 lines of code I would probably have used it. What are the pros and the cons compared to the “legacy” CustomEditor?
Yeah, actually that solved my problem… I feel so dumb. I wonder why I’ve used EditorSceneManager.MarkAllScenesDirty() all the time. I already a commented line with “EditorUtility.SetDirty()”, but I don’t remember why I commented it. Maybe I tried it together with “EditorSceneManager.MarkAllScenesDirty()” and it didn’t work, have no idea…