I am creating a simple tilemap editor extention in unity because the default one lacks a lot of functionality my project needs. I am inheriting EditorWindow. When holding the left mouse button and dragging the mouse i want to place tiles in the scene (in editor mode).
The picture below illustrates what behavior i want.
:
The problem i face is how to recognize this event. This is the function for handling mouse input that i use:
void HandleMouseInput() {
Event e = Event.current;
switch (e.type) {
case EventType.MouseDown:
if (e.button == 0) PlaceTile();
break;
case EventType.MouseMove:
Debug.Log("Moving");
Debug.Log(e.button); // <-- always show 0 (left click) even though mouse is not clicked.
break;
}
}
The first case (single tile placement) works as expected. But i fail to capture the "left mouse button held down" event. I can capture a mouse move event EventType.MouseMove but i then need whether there was a left click. According to unity docs, e.button == 0 indicates a left click (which works as expected in the first switch case). But in the second case e.button is always 0, regardless of what mouse button is clicked. There is a EventType.MouseDrag aswell but it seems to only trigger when you select a gameobject in the scene and drag it.
In Unity, when holding down the left mouse button and moving the mouse the default behavior seems to be creating a selection box:

Or dragging the entire scene if the hand icon is selected in the top left corner of the editor.
Essentially i want to capture this event and override the result with my own functionality.
EDIT: I think i could solve this by creating a custom tool https://docs.unity3d.com/ScriptReference/EditorTools.EditorTool.html
Alright so instead of inheriting EditorWindow i created a custom tool TileTool and put all the logic in there.
In its OnToolGUI (OnGUI equivalent?) i can disable the box selection:
HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
And automagically the event EventType.MouseDrag is captured correctly and i achieve the desired effect.
The whole script:
[EditorTool("Tile Tool")]
class TileTool : EditorTool
{
// Serialize this value to set a default value in the Inspector.
[SerializeField]
Texture2D icon;
public override GUIContent toolbarIcon =>
new GUIContent() {
image = icon,
text = "Tile Tool",
tooltip = "Tile Tool"
};
public override void OnToolGUI(EditorWindow window) {
HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
HandleMouse();
}
void HandleMouse() {
Event e = Event.current;
switch (e.type) {
case EventType.MouseDown:
if (e.button == 0) ApplyLeftClickTool();
break;
case EventType.MouseDrag:
if (e.button == 0) ApplyLeftClickTool();
break;
}
}
void ApplyLeftClickTool() {
switch (TilemapEditor.Instance().ActiveTool) {
case TilemapEditor.TileTool.BRUSH:
PlaceTile();
break;
case TilemapEditor.TileTool.ERASER:
EraseTile();
break;
}
}
void PlaceTile() {
GameObject prefab = TilemapEditor.Instance().Selected;
GetTilemap().Place(prefab, MouseInWorld());
}
void EraseTile() {
GetTilemap().Erase(MouseInWorld());
}
PrefabTilemap GetTilemap() {
PrefabTilemap tilemap = FindObjectOfType<PrefabTilemap>();
if (tilemap == null) {
GameObject tilemapGO = new GameObject("Tilemap");
tilemap = tilemapGO.AddComponent<PrefabTilemap>();
tilemap.Init();
}
return tilemap;
}
Vector2 MouseInWorld() {
return HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With