- Home /
Associate my custom asset with a custom EditorWindow
Hello,
In the Project pane, when I right-click on an Animation Controller and select Open, it opens the Animator window.
I have a custom asset in the Project pane. When I right-click on it, I see the Open menu item but it doesn't do anything. I'd like to have it open my custom EditorWindow. Does anyone know how to do this?
(Please note, this is not the same as having a custom Editor in the Inspector pane - which is working fine!)
EDIT - Feb 20th.
I have two "almost" solutions. I'm posting them here in the hope that someone can turn one of them into a proper solution. Failing that, they might be useful to someone else…
Half-solution 1
The following code will get a callback with the user tries to open an asset. Unfortunately, this is only for assets which are going to be opened in external tools - like .cs files. It doesn't fire for my custom asset (Scriptable object). This feature was introduced in Unity 4.2
public class OpenAssetCallback
{
[UnityEditor.Callbacks.OnOpenAsset(1)]
public static bool OnOpenAsset(int instanceID, int line)
{
Debug.Log(string.Format("Going to open asset {0} at line {1}", instanceID, line));
return false;
}
}
Half-solution 2 The following code will create a new Asset>Open menu item. But of course, you lose all the existing functionality. So even if you re-implemented all the existing functionality, this approach wouldn't scale to support 2 or more custom extensions that didn't know about each other.
public class OpenAssetCallback
{
[MenuItem("Assets/Open")]
public static void Execute()
{
Debug.Log("User wants to open the selected asset...");
}
}
Do you have access to your "Open" button? If you do, then you can write a menu item to open up your window, and then use EditorAppliction.Execute$$anonymous$$enuItem
to execute it.
hi @vexe, thanks for taking the time to comment. Getting access to the "Open" button is pretty much what the question is about. (Writing the handler/opening the window should be trivial.) I've updated my question with my latest progress in case this gives you any ideas.
Answer by nmad · May 18, 2015 at 10:30 AM
I think this is a necropost but I just found a good answer for this ... Using "OnOpenAsset" callback, you can try to cast the selected active object to your type. Ie:
[UnityEditor.Callbacks.OnOpenAsset(1)]
public static bool OnOpenAsset(int instanceID, int line)
{
if (Selection.activeObject as YourScriptableObject != null) {
OpenYourScriptableObjectEditorWindow();
return true; //catch open file
}
return false; // let unity open the file
}
Thank you very much for this simple and straightforward answer. Saved me so much time!
Beware: Selection.activeObject may not be the object that triggered OnOpenAsset. For example, if you click a compiler error in Console, OnOpenAsset's instanceID will be pointing at the code file, while Selection.activeObject will be the last object you selected in project view. See my answer below that fixes this.
Answer by maccesch · Aug 14, 2014 at 02:07 AM
I found a bit of an hackish solution:
Write a custom Editor
(inspector) for your asset and inside its OnEnable()
method open your EditorWindow
.
[CustomEditor(typeof(YourAsset))]
public class YourAssetEditor : Editor {
void OnEnable() {
YourAssetEditorWindow window =
EditorWindow.GetWindow<YourAssetEditorWindow>();
window.yourAsset = (YourAsset) target;
}
}
When you click on your asset the window is immediately shown. If you don't want that you could use a button in your custom inspector. Both solutions aren't perfect but it works.
from me! Your idea is as good as any of $$anonymous$$e. $$anonymous$$aybe Unity 5 will allow us to bind assets to custom-editors "properly". Till then, thanks for taking the time to post your answer.
Guys.. I am really noob with this can you explain this further? I really want to apply this in my project. thanks.
Answer by alex_roboto · Jan 13, 2020 at 10:37 AM
Necro so people googling can find the right answer. Selection.activeObject is not always updated when OnOpenAsset is called. This means Selection.activeObject may be some random object. For example, when you click a build error in the console, OnOpenAsset will be called but Selection.activeObject will be the last selected object, not the build error, and the last editor window will open rather than the code editor. Here's the more correct way of doing it:
public static bool OnOpenAsset(int instanceID, int line)
{
string assetPath = AssetDatabase.GetAssetPath(instanceID);
YourScriptableObjectType scriptableObject = AssetDatabase.LoadAssetAtPath<YourScriptableObjectType>(assetPath);
if (scriptableObject != null)
{
YourWindow window = (GameObjectDataEditorWindow)GetWindow(typeof(YourWindow ));
window.SetScriptableObject(scriptableObject);
window.Show();
return true;
}
return false; //let unity open it.
}
Worth mentioning that SetScriptableObject() and Show() are to be written by the person reading this. Also, I would use Object o = UnityEditor.EditorUtility.InstanceIDToObject(instanceID);
followed by if (o is YourType x) { // remaining code here }
instead.
Your answer
Follow this Question
Related Questions
SerializedPropertyTable in custom editor window 1 Answer
When is the best time to call Repaint(); in an editor window 1 Answer
Detect Enter Key Event with GUILayout.TextField Focused 1 Answer
Listen to Keyboard Events on EditorWindow 1 Answer
Undo.RecordObject and Constructor of Serializable Class 0 Answers