- Home /
OnSelectionChange Without EditorWindow
Hello To All!
Is there a way to detected Changes in Hierarchy much like the EditorWindow.OnSelectionChange () but without having the editor window open?
I am writing an Editor tool that needs to detect Changes in the current scene exactly like the EditorWindow.OnSelectionChange (). Upon selection i display onScreen information about current selection and provide some manipulation options outside the tool panel.
Once script initiated the window itself does not provide any "Visual" functionality anymore. But its necessary for dispatching relative events like Update & OnSelectionChange.
It would be Useful then if i could still detect this events Without the editor window being opened. That way i can ensure that the tool still functions properly even if the designer has closed the window or has just maximised the Scene View.
i have manage to find a way to detect Update events with :
EditorApplication.update += Update;
But i cant find a way to detect selection changes!
Thanks In Advance!
$$anonymous$$ay I know the exact purpose and where it is being used?
In sort i am doing some object manipulation (positioning , rotation...) and i would like to give the ability to Designer to have more available workspace, for example maximize the scene view window.
I'm not sure I fully understand the question. Could you elaborate more? what type of changes you're interested to detect?
Since i was not to clear i edited the question with more info!
not sure but, does a static class work here (it'll always run in the background)? (mocked with InitializeOnLoad]
Answer by whydoidoit · Feb 21, 2014 at 08:53 AM
Every time you get an Update - check whether Selection.activeObject has changed.
I think this where i am leading towards. At least if the tab/window is not open. But ill have to compare the Selection.gameObject array cause Selection.activeObject doesn't change if you add more items to the selection. Do you think that will add overhead to the editor?
Check if Selection.gameObjects.Length
changes: no overhead. Assu$$anonymous$$g Selection caches the selected gameobject array...
Agree with Jamora - that's the easiest way, covers all but extreme edge cases.
Agreed As well! Did a quick test and seems to work! Thanks Everybody!
Answer by Immanuel-Scholz · Sep 09, 2015 at 07:44 AM
Since Unity 5.2, there is now a callback Selection.selectionChange
I write Selection.selectionChange += myEditorWindow.OnSelectionChanged in init method but EditorWindow can't receive that callback
That makes no sense ^^. You seem to use an EditorWindow. The editor window class gets this callback automatically when it's open. See the docs (scroll down to "$$anonymous$$essages") there you will see the OnSelectionChange message..
This question here was about how to get that callback without having an editor window class. The Selection.selectionChange
event does exactly that.
If you have a problem with your editor class / window you might want to ask a seperate question. You provided almost no information, also as said this question has a different topic, so you seem to be wrong here.
When you ask a new question, make sure you describe your problem in detail. Especially add what you actually want to do.
EDIT: That previous solution actually had a few other issues. After messing around for a while... I realized there was a much easier solution and face palmed. All I have to do is check in OnDisable if the Selection.activeObject != (($$anonymous$$yBehavior)target).gameObject before running the code and it will let me know if this is a deselect or just some refresh.
Below is left for posterity, problem solved
EDIT: I just realized that my problem was being caused by the fact that each time OnEnable is called, it's attempting to deregister and register an entirely new instance of OnSelectionChanged. $$anonymous$$y solution was to make the function static. I can't force it to only fire on exit anymore though, since I can't know which object I'm in... but that's okay because I'm only running code that clears states that will be cleared on entering anyway.
I'm having a hard time figuring out when I should register my method to Selection.selectionChange.
OnEnable and OnDisable are actually called before that event is called. So if I try to register it in OnEnable and unregister it in OnDisable, it only fires when I select the object but not when I deselect it.
I tried putting this in OnEnable:
Selection.selectionChanged -= OnSelectionChanged;
Selection.selectionChanged += OnSelectionChanged;
However, the unregistration seems to go ignored.
Any advice?
Answer by MakeCodeNow · Feb 21, 2014 at 06:55 AM
As far as I know, there is no way to get any of those extremely useful callbacks aside from having an EditorWindow subclass. However, I believe that docked windows will get those events, so you can just make a window and have your designers dock it next to something they actually use.
Yeah they do! i also made the window information to be togglable but if you maximize the scene view then it stop working again!-)
If you add the [InitializeOnLoad] attribute to a static class, then you can receive those callbacks without an EditorWindow subclass:
[InitializeOnLoad]
public static class $$anonymous$$yCustomSelectionThingy
{
private static bool _isRegistered = false;
static $$anonymous$$yCustomSelectionThingy()
{
if ( !_isRegistered )
{
_isRegistered = true;
Selection.selectionChanged += OnSelectionChanged;
EditorApplication.update += OnEditorUpdate;
}
}
private static void OnSelectionChanged()
{
_didSelectionChange = true;
}
private static void OnEditorUpdate()
{
if ( _didSelectionChange )
{
_didSelectionChange = false;
// do some custom selection thing here
}
}
}