I followed this tutorial to make a camera I can control with WASD or by dragging the mouse. Here is the code:

`extends Camera2D

@export var zoomSpeed : float = 9
@export var zoomLimit: float = 4
var zoomTarget: Vector2 = Vector2.ZERO
var moveTarget: Vector2 = Vector2.ZERO

var dragStartMousePos: Vector2 = Vector2.ZERO
var dragStartCameraPos: Vector2 = Vector2.ZERO
var isDragging: bool = false

func _ready():
zoomTarget = zoom
moveTarget = position

func _process(delta):
Zoom(delta)
SimplePan(delta)
ClickAndDrag()

func Zoom(delta):
var zoom_min: Vector2 = Vector2(zoomLimit, zoomLimit)
var zoom_max: Vector2 = Vector2(5.0, 5.0)
if Input.is_action_just_pressed("camera_zoom_in"):
zoomTarget *= 1.1
elif Input.is_action_just_pressed("camera_zoom_out"):
zoomTarget *= 0.9

zoomTarget = clamp(zoomTarget, zoom_min, zoom_max)
zoom = zoom.slerp(zoomTarget, zoomSpeed * delta)

func SimplePan(delta):
var moveAmount = Vector2.ZERO
moveAmount = Input.get_vector("camera_move_left", "camera_move_right", "camera_move_up", "camera_move_down")
moveAmount = moveAmount.normalized()

if !isDragging:
	moveTarget += moveAmount * 15 * 1/zoom.x
	position = position.lerp(moveTarget, 7 * delta)

func ClickAndDrag():
if !isDragging and Input.is_action_just_pressed("camera_pan"):
dragStartMousePos = get_viewport().get_mouse_position()
dragStartCameraPos = position
isDragging = true
if isDragging and Input.is_action_just_released("camera_pan"):
isDragging = false
moveTarget = position

if isDragging:
	var moveVector = get_viewport().get_mouse_position() - dragStartMousePos
	position = dragStartCameraPos - moveVector * 1/zoom.x

func focus_on_object(object):
moveTarget = object.global_position`

Now I'd like to limit the camera to a predefined area, but trying to do so with the built-in limit variables can make it act funky. Any suggestions?

  • xyz replied to this.

    format coede with ``` tags pls

    xyz When Camera2d's built-in limits are enabled, the camera will indeed stop at the limits. However, if using WASD or panning at the limits as if to "move past" the limits, the camera will get stuck and will need to be "moved back," as if it were indeed moved past the limits. I believe I know why this happens: WASD and panning are tied to the "moveTarget" variable (which the "position" variable follows) rather than "position," so while the position is clamped inside the limits, the moveTarget is not. I'm unsure however of how to go about clamping the moveTarget variable, or if that is even the right approach.

    • xyz replied to this.

      Isaac Why don't you just update position directly?

        xyz To have smoother camera movements. Also for panning to work correctly, you must use a separate variable.

        • xyz replied to this.

          Isaac How about using camera's built-in smoothing?