Search code examples
unity-game-enginescriptable-object

Editor script: refer to selected ScriptableObject


Another way to phrase this question would be "Get ScriptableObject from selection in editor code".

I have a public class DialogueObject : ScriptableObject from which I create many SOs. I'd like to automate some actions around these SOs like populating data using editor script but I can't figure out or Google-Fu how to get a handle on them.

This does not work (NullReferenceException):

DialogueObject obj = Selection.activeGameObject.GetComponent<DialogueObject>();

So, how to select a ScriptableObject in the project window and edit it's data via editor scripting?

Update: I discovered that taking it as a public variable and assigning it in the inspector works (obj = (DialogueObject)EditorGUILayout.ObjectField("DialogueObject", obj, typeof(DialogueObject));), but I'd prefer to lift it from the Selection object instead, so still looking for help.


Solution

  • In this case you need a custom EditorWindow. And in this editor window we can use one of the Unity Editor Events which is OnSelectionChange(), by events I mean all the message methods which are called by the Unity itself ie. Awake, OnEnable, Start, Update, etc...

    OnSelectionChange() will be called when ever you select an object, regardless of Scene Hierarchy or Project View. Now you just have to get a selected object using Selection.activeObject;. After getting the current selected object you can compare and cast it to your SO type. and can draw a custom editor based on your needs.

    Below is an example of a such simple:

    public class SoEditor : EditorWindow
    {
        [MenuItem("Tools/SoScript")] //To show an editor window...
        public static void ShowEditorWindow()
        {
            GetWindow<SoEditor>();
        }
    
        //This is one of the Unity message which is being called when ever the selection gets changed.
        public void OnSelectionChange()
        {
            var obj = Selection.activeObject; //Get the object/
    
            if (obj == null) //Check for the null.
                return;
    
            if (obj.GetType() == typeof(SoScript))
            {
                SoScript sos = obj as SoScript; //Here is your type casted object.
    
                ///Draw or populate your editor fields here...
            }
        }
    }
    

    Note: Make sure that you are using Selection.activeObject and not Selection.activeGameObject Otherwise you will get a Null Exception if the selected object is not a GameObject.

    Hope this gets you to your solution...✌️

    Referances: EditorWindow EditorWindow.OnSelectionChange()