I have a ScriptableObject and I want to make an editor so that when the instance of the ScriptableObject is selected in the inspector, it displays a position handle at a point based on a Vector3 variable saved in the ScriptableObject. I want to make it so that when the handle is moved, the variable within the ScriptableObject will update. Pretty much all handle examples I found on the internet use MonoBehaviours. How can I make this work?
I have the same issue, can’t find anything after hours of googling and trying
Hello @Malvern ,
Even though it’s quite late, I’d like to share a solution to this problem. I had the same problem too, and I stumbled upon this post about mastering unity editor handles: Unity Live Help
Search for ScriptableObject in the post and you’ll find an implementation for undo/redo. Here is the link to the script on Github: MasterUnityHandles/ExamplesScenes/Editor/CurveScriptableObjectEditor.cs at master · alelievr/MasterUnityHandles · GitHub
To make this work, first, you have to register/unregister OnSceneGUI
for the event SceneView.duringSceneGui
since onSceneGUIDelegated
is deprecated. Next, pay attention to the OnSceneGUI(SceneView sv)
method, you’ll see the GUI.changed
check. If changed, you just have to apply the changes made during Handles.PositionHandle
operation or whichever method of your choice, back to the target.
Example code:
MyScriptableObject.cs
using UnityEngine;
[CreateAssetMenu(fileName = "New SO", menuName = "Create New SO")]
public class MyScriptableObject : ScriptableObject
{
public Vector3 point;
}
MyScriptableObjectEditor.cs
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(MyScriptableObject))]
public class MyScriptableObjectEditor : Editor
{
void OnEnable()
{
SceneView.duringSceneGui += OnSceneGUI;
}
void OnDisable()
{
SceneView.duringSceneGui -= OnSceneGUI;
}
void OnSceneGUI(SceneView sv)
{
MyScriptableObject mySO = (MyScriptableObject)target;
Vector3 point = mySO.point;
point = Handles.PositionHandle(point, Quaternion.identity);
if (GUI.changed)
{
// for undo operation
Undo.RecordObject(target, "Move Point");
// apply changes back to target component
mySO.point = point;
}
}
}
Hope this helps.
© 2022 - 2025 — McMap. All rights reserved.
This is exactly what I was after, thank you!
– Freddiefreddy