I don't understand how to, for example, put sliders back where they were. Here's a test script, that will adjust the alpha value of the _Color property for a Material. Where I have lines commented out, I think I may be onto the right track, but am not sure. Please lead me further down said track, or reroute me.
using UnityEngine;
using UnityEditor;
public class UndoTestWindow : EditorWindow {
static UndoTestWindow window;
static Material material;
[MenuItem("Assets/Adjust Main Color Alpha", true)] static bool Validate () {
if (window) return false;
try {material = (Selection.activeObject as GameObject).renderer.sharedMaterial;}
catch {material = Selection.activeObject as Material;}
return material ? material.HasProperty("_Color") : false;
}
[MenuItem ("Assets/Adjust Main Color Alpha", false, 2000)] static void Open () {
window = GetWindow<UndoTestWindow>(true, material.name);
}
void OnGUI () {
// Event currentEvent = Event.current;
// if (currentEvent.button == 0 && currentEvent.isMouse) {
// Undo.SetSnapshotTarget(window, "Adjust " + material.name + " Main Color Alpha");
// Undo.CreateSnapshot();
// Undo.RegisterSnapshot();
// }
Color color = material.color;
color.a = EditorGUILayout.Slider("Main Color Alpha", color.a, 0, 1);
material.color = color;
// if (GUI.changed) EditorUtility.SetDirty(window);
}
}
I've learned that I can undo the operation, if I do
Undo.SetSnapshotTarget(material...
...but that only makes the material itself update, not the EditorWindow slider.
P.S. This is the first time I've ever used try/catch, so if you don't think that's a good use of it, for the validation function, please let me know. It seemed very concise.
EDIT: Here's what I've got, in OnGUI, that seems to be working. (Thanks to Daniele.) It seems like there ought to be a better way, to me please let me know if you ever come up with that way:
bool listeningForGuiChanges;
void OnGUI () {
Event currentEvent = Event.current;
if (currentEvent.type == EventType.MouseDown && currentEvent.button == 0) {
Undo.SetSnapshotTarget(material, "Adjust " + material.name + " Main Color Alpha");
Undo.CreateSnapshot();
Undo.ClearSnapshotTarget();
listeningForGuiChanges = true;
}
Color color = material.color;
color.a = EditorGUILayout.Slider("Main Color Alpha", color.a, 0, 1);
material.color = color;
if (listeningForGuiChanges && GUI.changed) {
Undo.SetSnapshotTarget(material, "Adjust " + material.name + " Main Color Alpha");
Undo.RegisterSnapshot();
listeningForGuiChanges = false;
}
}
Id say that is improper usage of try/catch but I can't find a good article to back it up. However, in your case it probably won't do much of a difference to do it otherwise. You can try look for "best practices" on the topic of exception handling.
– Statementwith try catch you are catching exceptions, so from my POV, catch is for exceptional circumstances only and not for the things that would occur in normal operation. Naturally it works fine, but if you were working on a large project and just catching general exceptions it starts to not scale well.
– Bovine