How to drag camera with mouse?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By victordevtb

How can i drag my camera2d with mouse?

:bust_in_silhouette: Reply From: pgregory

Your question is a bit vague, I’d recommend adding a bit more context to get a better answer, however, making some assumptions about your question, here is my advice.

  1. Create a root node Node2D in the 2D scene.

  2. Create a KinematicBody2D as a child of the root.

  3. Create a CollisionShape2D as a child of that.

  4. Create a Sprite, also as a child of the KinematicBody2D, and assign a texture.

  5. Add a shape to the CollisionShape2D and adjust it to fit your sprite.

  6. Create a Camera2D, also as a child of the KinematicBody2D.

  7. Create some background assets under the root Node2D as appropriate.

  8. Add the following code to the KinematicBody2D

    extends KinematicBody2D
    var dragging = false
    
    func _ready():
    	set_process_input(true)
    
    func _input(event):
    	if event is InputEventMouseButton:
    		if event.is_pressed():
    			dragging = true
    		else:
    			dragging = false
    	elif event is InputEventMouseMotion and dragging:
    		position = get_global_mouse_position()
  1. Make the Camera2D current by selecting the flag, and optionally enable or disable the Drag Margin flags, depending on how you want it to move.

That should do it, if you drag the sprite around now, the camera should follow. You may find it a bit difficult to control, so it might be wise to add some speed control or something, depending on the effect you’re after.

For reference, I’ve put a simple sample project here that shows what I’ve just described.

pgregory

This seems way over complicated for such a simple thing. I’m still learning Godot and but I was able to get a camera to pan with this code:

extends Camera2D
class_name MainCamera

var _previousPosition: Vector2 = Vector2(0, 0);
var _moveCamera: bool = false;

func _unhandled_input(event: InputEvent):
if event is InputEventMouseButton && event.button_index == BUTTON_LEFT:
	get_tree().set_input_as_handled();
	if event.is_pressed():
		_previousPosition = event.position;
		_moveCamera = true;
	else:
		_moveCamera = false;
elif event is InputEventMouseMotion && _moveCamera:
	get_tree().set_input_as_handled();
	position += (_previousPosition - event.position);
	_previousPosition = event.position;

Why not recommend something like this to people?

rybadour | 2019-03-20 23:33

I haven’t tried your code out, but from an initial scan it looks like your code would move the camera irrespective of where the mouse had been clicked. As I mentioned in my solution, the question is a bit vague, I was basing my answer on the specifics of “drag”, meaning to me, dragging a particular ‘thing’ around in the scene to move the view. If the required solution is to just move the camera in response to any mouse movement, anywhere, then yes, your solution would probably do the right thing.

pgregory | 2019-03-21 00:02

This worked perfectly. Thanks

ishfwilf | 2020-11-07 17:30

:bust_in_silhouette: Reply From: Keeyan

This is based party on pgregory’s code.

I simply attached this script to active Camera:

extends Camera2D

var mouse_start_pos
var screen_start_position

var dragging = false


func _input(event):
	if event.is_action("drag"):
		if event.is_pressed():
			mouse_start_pos = event.position
			screen_start_position = position
			dragging = true
		else:
			dragging = false
	elif event is InputEventMouseMotion and dragging:
		position = zoom * (mouse_start_pos - event.position) + screen_start_position

The zoom * is there so that if the camera is zoomed in or out, the scroll will be relative to the zoom.

I also added a “drag” event on the “input Map” in project settings, which for me is the middle mouse button. However just putting event is InputEventMouseButton: instead should work for the left click.

Very late answer but exactly what I needed, thanks a lot :smiley:

Mudderhino | 2021-09-08 16:19

Any idea on how to make it go to the inverse direction?

Nobel | 2021-11-17 12:00

change

(mouse_start_pos - event.position)

to

-(mouse_start_pos - event.position)

AI | 2021-12-11 18:26

Hey everyone!

Any idea how to make it so that the camera can not go to infinity?

ThePiet | 2022-02-05 18:50

I actually needed to divide by the zoom instead of multiplying by it for it to work correctly, maybe this will save someone some time.

filkata | 2023-05-07 20:59

Script updated for 4.2.1

# ty rybadour
# https://forum.godotengine.org/t/how-to-drag-camera-with-mouse/28508/2

extends Camera2D
class_name MainCamera

var _previousPosition: Vector2 = Vector2(0, 0);
var _moveCamera: bool = false;

func _unhandled_input(event: InputEvent):
	if event is InputEventMouseButton && event.button_index == MOUSE_BUTTON_LEFT:
		get_viewport().set_input_as_handled();
		if event.is_pressed():
			_previousPosition = event.position;
			_moveCamera = true;
		else:
			_moveCamera = false;
	elif event is InputEventMouseMotion && _moveCamera:
		get_viewport().set_input_as_handled();
		position += (_previousPosition - event.position);
		_previousPosition = event.position;