Game Development tutorials
Game Development  journey
Beginner "how to" tutorials , programming, software usage,  artwork, news  and more
For TIPS and SHORT TUTORIALS
 FOLLOW 
100+

Grab game objects with the mouse or screen touch in Godot Engine

Posted by Vix Mark on October 12No Comments
how to grab game objects with mouse
Manipulating game objects with a mouse

For this Demo I created a new project in Godot with a new Scene named Field. Field contains Node2D of the same name (by default, main Node's name becomes a Scene name upon saving) and 3 children - Sprites: Background, Player, and Mouse. Player's also got a child Node - Button.

Button will serve as a "grabbable area". It will be transparent and it will also send signal when mouse click or touch happens within area (button_down) and another one - (button_up) when finger or mouse button is released.

Click on Button in the Scene Tree then choose a Move Mode on the Instruments panel or by pressing 'W' key and locate that button representing rectangle in 2D World editor to the position that your grabbable area should be at.

Scene Tree. Botton Node
Grabbable area position

To enlarge the button area press 'Q' key or click an arrow next to the Mode Mode tool on the panel. Now you're able to click on the circles appeared around the perimeter of the Button rectangle and drag its sides, making area bigger or smaller.

Overriding Button's theme. StyleBoxEmpty and transparency

This is the initial setup. And yes, I almost forgot to mention how to make the button transparent, because by default it's instanced with a background.

In Inspector Panel of Button under the Control category find Theme Override subcategory and unfold Styles. For every button state (normal, hovered, pressed...) I assigned StyleBoxEmpty - an empty (shows nothing) resource that inherits from StyleBox - a base class used by Godot to provide the stylized boxes for the UI elements.

Button Theme Override

StyleBoxEmpty comes in handy when we need to make some area, used by UI element, to be invisible during the gameplay. So, the button will be there and I will be able to click it and grab the player with my mouse but it will be transparent. Just as I need!

How to actually grab an object in Godot Engine, rotate or drag it. Coding behavior

At this moment my Demo doesn't really do much. If I start the Scene by pressing F6 objects stay still.

The logic I'm about to implement is pretty straightforward: the script 'toggles' active variable between true and false on received signals button_down and button_up. Then _process() function runs code if active == true (mouse button is being clicked).

Implementing rotation using mouse

Let's say I want to rotate a player using my mouse. The code inside that if statement would need to 'grab' current cursor position (CP) and player position (PP ), create a vector by subtracting PP from CP and then find the angle between that vector and X axis.

func _process(_delta):
	if active:
		# Getting current mouse position in (Global COORD.)
		var mouse_position = get_viewport().get_mouse_position()
		
		# Player's Transformation Matrix in Canvas coordinates
		# Getting Player's position. I'll use it as the Pivot point
		var pivot = $Player.get_global_transform_with_canvas().origin

		# Creating a vector by subtraction.
		var vector = (mouse_position - pivot).normalized()
		# Calculating the angle. 
		var angle = PI/2 + vector.angle()

		$Player.rotation = angle

func _on_Button_button_down():
	active = true
	$Mouse.scale = Vector2(3, 3)


func _on_Button_button_up():
	active = false
	$Mouse.scale = Vector2(2, 2)

Let's take a look at the code above.

  • First, I get the global mouse position
  • Find out my player's position in the Canvas coordinates. I use player's Transformation Matrix' origin Vector, which provides player's position within the Canvas. It'll be used as a pivot point.
  • Now, I need to have a vector with the origin at the pivot point, pointing at the current mouse position. .normilize() method shortens vector's length to one unit.
  • At this point I can calculate the angle: .angle() method returns a vector's angle with respect to positive X axis. I also add 90 degrees (PI/2) to the final result because I want my player to be 'looking up'

.angle() method returns -PI/2 when the object's pointing up. An imaginary vector has to travel PI/2 radians or 90 degrees to the left to be pointing up, that's why it's negative.

Additional tweaks

For demonstration purposes I drew a small red circle png image and assign it to a texture property of Mouse Sprite Node. This circle will be following the cursor or a finger on a touch screen. If a click or a touch happens the red circle will grow bigger and follow the object while it's being dragged and rotated. Once the dragging stops the circle returns to its initial size.

Demo. Cursor pointer scale up/down

Check out the script above. I change Mouse Node scale under _on_Button_button_up() and _on_Button_button_down() methods. Additionally, we need to make sure that the red circle gets mouse's global position every frame. Add the following line just under the _process(_delta):

func _process(_delta):
	$Mouse.global_position = get_viewport().get_mouse_position()

Summary

I created a new project, made a new Scene and added Sprite Nodes to the main Field Node. Then, I added Button Node as a child of my Player, attached a new script to the Scene and connected Button signals to that Script. After that, I wrote a code to make my Player do what I want - rotate while the left mouse button's being clicked and dragged. The red circle pointer helps to identify the cursor position if I use a touch screen.

How to simply drag game objects in Godot Engine using mouse I will explain in the second part.

If you find this article useful, follow me on Instagram for more tips and learning materials.

Share this
Pin it
Conversation
5 1 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
©2026 GamaDevFcups - how to make Indie Games.

Game Development: Godot Engine, Krita, Blender, programming, tutorials

GameDevFcups

Desidned and built by VixStudio
 | 
VixMark@protonmail.com
pointer-down
0
Would love your thoughts, please comment.x
()
x