Easier Top-down Panning Camera

Godot Version

v4.6.2.stable.official [71f334935]

Question

Hello! I’m working on a RTS game (like StarCraft II or Command & Conquer), and I have implemented a camera that can be panned around by moving your cursor to the edges of the screen. I’m manually checking if the cursor is within certain areas (if get_viewport().get_mouse_position().x < 135:, etc.)

Is there an easier and more flexible way to do this?

You could maybe use an

@export var panning_margin := 135

To experiment a little using remote debug.

I assume you’re using the viewport rect for right- and bottom- side panning detection?

if get_viewport().get_mouse_position().x > get_viewport_rect().size.x - 135:
# do pan

If your game has support for multiple resolutions you might want to multiply this margin accordingly…

What type of more flexible approach are you imagining yourself?

No, actually! That’s a good idea, and pretty much exactly the kind of flexibility I was looking for. I’m going to let players customize almost everything, so the panning margins could be one option.

I hope to include multiple resolution support in the future. What do you mean by accordingly? Should I just divide the panning margin by (current x resolution / full x resolution)?

You could also check out my Camera2D Plugin. It’s free and open source. Just drop a Camera2DPan node on your Camera2D and configure it.

It supports edge scrolling with the mouse, panning with the number pad on the keyboard, panning with the right stick of a controller, and two-finger screen drag with a mouse.

If your game is a 3D game, you’ll have to translate it to 3D, but it all the interface code will be the same.

Also, if you want to support multiple resolutions, I recommend checking out my Display Plugin, which supports that, as well as multiple monitors, full screen, and saving all the settings out of the box.

That is an amazing plugin. I’ve never seen anything like it, but it sounds like the exact thing I need. Thank you!

Funnily enough, we’re using (almost) the same method of scrolling. Great minds think alike

	var pan_direction: Vector2i = Vector2i(0, 0)
	if mouse_position.y < PAN_TOP_MARGIN:
		pan_direction.y -= 1
	if mouse_position.y > PAN_BOTTOM_MARGIN:
		pan_direction.y += 1
	if mouse_position.x < PAN_LEFT_MARGIN:
		pan_direction.x -= 1
	if mouse_position.x > PAN_RIGHT_MARGIN:
		pan_direction.x += 1
	
	var cursor: CompressedTexture2D = cursors[pan_direction.y + 1][pan_direction.x + 1]
	var cimage = resize_cursor(cursor.get_image())
	Input.set_custom_mouse_cursor(cimage, Input.CURSOR_ARROW)
	
	pan_direction *= PAN_SPEED
	global_position += pan_direction * delta