Is it possible to open ScriptableObjects in custom editor cindows with double click?

Hey,
I have a Question currently I am working on a custom Editor and I know how to load a file over an “Open File” Button but is there a way to open a ScriptableObject with a double click and then show the window?

Thanks for answers!
Bennet

You can use the OnOpenAsset attribute for this, a little hidden gem

[OnOpenAsset]
//Handles opening the editor window when double-clicking project files
public static bool OnOpenAsset(int instanceID, int line)
{
    DruidProject project = EditorUtility.InstanceIDToObject(instanceID) as DruidProject;
    if (project != null)
    {
        DruidEditorWindow.OpenProjectFile(project);
        return true;
    }
    return false;
}
//Handles correct behaviour when double-clicking a .watermesh asset assigned to a field
[OnOpenAsset]
public static bool OnOpenAsset(int instanceID, int line)
{
    Object target = EditorUtility.InstanceIDToObject(instanceID);

    if (target is Mesh)
    {
        var path = AssetDatabase.GetAssetPath(instanceID);
   
        if (Path.GetExtension(path) != ".watermesh") return false;

        Selection.activeObject = target;
        return true;
    }
 
    return false;
}
10 Likes

Thanks

In case anyone needs an example of this, here is how it worked for me in an existing serializableObject class that I made an editorWindow for.

(this is in 2022.0.b13)

using UnityEditor;
using UnityEditor.Callbacks;
using UnityEngine;

public class GameStateFlow : ScriptableObject
{
    public GameStateNodeData[] NodeData;

    [OnOpenAssetAttribute(1)]
    public static bool OpenGameStateWindow(int instanceID, int line)
    {
        bool windowIsOpen = EditorWindow.HasOpenInstances<GameStateGraphWindow>();
        if (!windowIsOpen)
        {
            EditorWindow.CreateWindow<GameStateGraphWindow>();
        }
        else
        {
            EditorWindow.FocusWindowIfItsOpen<GameStateGraphWindow>();
        }

        // Window should now be open, proceed to next step to open file
        return false;
    }

    [OnOpenAssetAttribute(2)]
    public static bool OpenGameStateFlow(int instanceID, int line)
    {
        var window = EditorWindow.GetWindow<GameStateGraphWindow>();

        string assetPath = AssetDatabase.GetAssetPath(instanceID);
        window.LoadFromFile(assetPath);

        return true;
    }
}
3 Likes

I’m using my scriptable object in my game, so I can’t have it in the Editor folder. This means I can’t reference my EditorWindow class from my scriptable object. Does anyone have a solution for this?

I don’t think anyone said your scriptable object had to be in an editor folder.

Just put your Editor window in an editor folder, and give it a static method that’s decorated with the [OnOpenAsset] attribute, and keep all your editor code outside your runtime scriptable object.

2 Likes

Solved my problem! Thank you.

I have a custom GraphViewEditorWindow and an associated Graph-ScriptableObject to store nodes, node data and edges. I was also looking for a way to open / focus the GraphViewEditorWindow upon double clicking any Graph-ScriptableObject and load its data.

I changed the code a little bit because it seemed redundant to handle the double click callback in two seperate steps.

    [OnOpenAssetAttribute]
    public static bool OpenGraphAsset(int instanceID, int line)
    {
// This gets called whenever ANY asset is double clicked 
// So we gotta check if the asset is of the proper type
        UnityEngine.Object asset = EditorUtility.InstanceIDToObject(instanceID);
        if (!(asset is Graph)) return false;

        bool windowIsOpen = EditorWindow.HasOpenInstances<GraphEditorWindow>();
        if (!windowIsOpen) EditorWindow.CreateWindow<GraphEditorWindow>();
        else EditorWindow.FocusWindowIfItsOpen<GraphEditorWindow>();

        GraphEditorWindow window = EditorWindow.GetWindow<GraphEditorWindow>();
        string assetPath = AssetDatabase.GetAssetPath(instanceID);
        string fileName = System.IO.Path.GetFileNameWithoutExtension(assetPath);
        window.LoadGraphAssetViaFileName(fileName);

        return true;
    }

The ScriptingReference page for OnOpenAssetAttribute has been removed from the documentation in versions higher than 2020.3.
Is there a reason for this, are we not supposed to use it anymore? Did it get deprecated?

Not sure! I opened up a project in 2023.2 and the attribute is still present and works as expected.

I just submitted a problem to documentation page. Otherwise, at a glance, I couldn’t find anything else that was meant to be a substitute.

1 Like