Automatic activation of EditorTool

I have a custom EditorTool that I want to automatically activate when an object gets selected. In other words, I want the same behaviour as you get for overlays with ITransientOverlay.

As far as I can tell, there’s no good way to achieve this currently. The EditorToolContext stuff looked like it might be it, but that just allows you to set up a context you can switch to, not one that’s forced for the selection.

I tried having the editor for the objects in question do ToolManager.SetActiveTool<MyTool>(); in OnEnable, but that causes exceptions;

InvalidOperationException: The current selection does not contain any objects editable by the component tool of type: MyTool

Even though selection.activeObject is a MyTool - there seems to be an ordering issue.

I think I will go back to just setting Tools.hidden = true when selection changes to my objects, and use OnSceneGUI + Handles, but EditorTools was supposed to be a new, modern way of achieving that. I really want to minimize the amount of clicks involved - when devs select my object, I want the tools to immediately be the correct ones for the object, instead of having to manually switch over to a different tool.

I believe I had the same or similar issue, a general purpose EditorTool that works for any GameObject.

I can’t recall what I did but from memory it was either subscribing the tool to the Transform component or I found a way to add my tool to the default EditorTool panel (the Select, Transform, Rotate, etc panel). Slight chance I never figured it out and relied on a custom component though.

You can combine an Initialize on load method with the Unity - Scripting API: Selection.selectionChanged action and always check for object type + part of scene or asset and probably some other checks. This is relatively brute force but it definitely works.

1 Like

Right! Thanks for pointing it out, I recall that I’ve actually done it this way at some point. :slight_smile:

Hi @Baste !

So as you said: “As far as I can tell, there’s no good way to achieve this currently.”

This is actually not a desired workflow in term of UX and not a recommended one in our guidelines so we didn’t make that possible. The reason is that we don’t want tools to suddently change in the middle of a workflow without a user decision.

Let’s say you are using the move tool, selecting a bunch of objects, and suddently selecting one that changes your tool to another… then you have to select the move tool again, and then you add another one that changes once more your tool unexpectedly…

That’s definitively not something we would like for our users.
If you want more information about the tooling system, please have a look at this new documentation about the workflows: The Contextual tooling.
It perfectly describes the workflow of these component tools:

  1. Select a GameObject.
  2. If the GameObject has a Component with Tools, those tools are shown as buttons in the Tools overlay, with a header icon to indicate their Component.
  3. Click the button to activate the Tool.
  4. Select a different GameObject, which has the same Component.
  5. The Component Tool remains active.
  6. Select a different GameObject, which does not have the same Component.
  7. The no-longer usable Component Tool is deactivated and removed from the Tools overlay.
  8. The last-used Transform Tool is activated (move, rotate, scale, etc).

I hope this helps :slight_smile:
Thomas

I mean, it helps in that I understand what your design goals are, and that thing are not going to change. I fundamentally disagree with your desired workflow. It requires extra clicks, which is bad, and it requires users to learn that there’s a button to click, which is also bad.

For the use case I have, there’s a single, correct, comfortable way to modify the GameObjects. I want the level designers to select the object, and then get the correct UI immediately without having to learn or remember a button.

In particular, this is a set of objects that have a start and an end point, and a middle section that is a mesh that’s automatically modified to stretch from the start to the end with the correct UVs and other settings. When either the start or end points are moved, the center point is automatically updated to move with them. Think straight pipes or conveyor belts or wires or whatever.

The best workflow would probably be to have an EditorToolContext that would be automatically selected when an object of that type was selected, and then be able to switch back to the default mode in the corner cases where that’s actually what they need.

Don’t get me wrong, I do think it’s good that you’re opinionated about how the overall workflow of the scene view should work. That has helped you improve quite a few tools. The problem is that in this case your opinion is wrong!
This is a rather small tool that will be relevant in some of the levels of our games. This means that for some of the level designers, there will be several weeks or even months between each time they use the tool. So if we have a workflow where I teach them “hey this auto line thing has it’s own button over the move tool that you can press to use it correctly”, they will do that now, and then some of them will naturally forget that the button exists by the next time they interact with those objects.
It’s much, much better if the correct tool context was the default one as they pressed the object, because then the scene view would inform them automatically that “hey, there’s a better way to interact with this object”.

For now, I can use OnSceneGUI, Handles and Tools.visible = false, but the downside with that is that I don’t automatically get things like grid snapping and whatnot. It would be much better if I could just set the EditorToolContext from code and have that work at any point, or if an EditorToolContext could be marked as default instead of optional.

Just days ago I wrote this in an ITransientOverlay:

		public Boolean visible
		{
			get
			{
				var selected = Selection.activeObject as GameObject;
				if (selected == null)
					return false;

				m_WeaponRigSetup = selected.GetComponentInParent<WeaponRigSetup>();
				return m_WeaponRigSetup != null;
			}
		}

Works like a charm. I just need to select the game object OR one of its children and the overlay is visible and allows the designer to quickly toggle weapons with a slider.

Yeah, that works great for overlays. That design is perfectly happy with just spawning the UI immediately without waiting for user input, so I’d love EditorTools to do the same.

ITransientEditorTool, perhaps?

I see, I assumed they would work the same.

But EditorTool is still component-based, right? So what if you were to add a “ToolComponent” of sorts to more objects than necessary such that the tool remains active, but only operates if the ToolComponent object also has the desired target component respectively it performs its action on all but the ones that don’t have the target component.

Just an idea for a workaround.

That design methodology is meant to help manage users that potentially aren’t tech savvy navigate websites, it’s not meant for game engine workflows… also and you guys dont even follow it yourselves, the terrain editor opens up a different set of tools. and so does poly brush.

even worse, I just finished a system where this design decision back fires and has the opposite effect too.

I made a extension to the physics bodies to allow for second order dynamics, springy movement, and it requires an empty target to follow. I wouldve liked to allow a dev to be able to move these seemingly like any other object, but because of this design decision, i cant, theyd either have to move the target or select a tool manually :face_with_raised_eyebrow: