Limit Camera Movement

Godot Version

4.3

Question

I have a 2D Scene with multiple TileMapLayers, and have created a script to allow the user to drag the Camera2D whilst holding the right mouse button:

extends Camera2D

var dragging = false
var last_mouse_position = Vector2()

func _input(event):
	if event is InputEventMouseButton:
		if event.button_index == MOUSE_BUTTON_RIGHT:
			dragging = event.pressed
			if dragging:
				last_mouse_position = event.position
				
	elif event is InputEventMouseMotion and dragging:
		var delta = event.position - last_mouse_position
		position -= delta
		last_mouse_position = event.position

I want to limit the movement of the camera so it doesn’t move past any edge of the base TileMapLayer so the TileMapLayers are always in view of the camera, but I am struggling to figure out how to work this. What would be a good way to achieve this?

Thanks in advance

The camera2d has a limit-property for every direction. This should do the trick

1 Like

Thank you.

I’ve been playing with this, and I am able to get it to work for the top and left, but the right hand side and bottom are off:

extends Camera2D

var dragging = false
var last_mouse_position = Vector2()

@export var limitTileMapLayer: TileMapLayer

func _ready() -> void:
	if limitTileMapLayer:
		var map_rect = limitTileMapLayer.get_used_rect()
		var map_size = Vector2(map_rect.size) * limitTileMapLayer.cell_size
		
		limit_left = map_rect.position.x * limitTileMapLayer.cell_size.x
		limit_top = map_rect.position.y * limitTileMapLayer.cell_size.y
		
		var window_size = DisplayServer.window_get_size()
		limit_right = (limit_left + map_size.x) - window_size.x / zoom.x
		limit_bottom = limit_top + map_size.y - window_size.y / zoom.y
	else:
		print("TileMapLayer not assigned")

func _input(event):
	if event is InputEventMouseButton:
		if event.button_index == MOUSE_BUTTON_RIGHT:
			dragging = event.pressed
			if dragging:
				last_mouse_position = event.position
				
	elif event is InputEventMouseMotion and dragging:
		var delta = event.position - last_mouse_position
		position -= delta
		last_mouse_position = event.position
		_clamp_position()

func _clamp_position():
	position.x = clamp(position.x, limit_left, limit_right)
	position.y = clamp(position.y, limit_top, limit_bottom)

how far off?

Approximately half the window width. When it finishes, the right edge of the map is approximately in the centre of the camera

then just apply this offset to the limit