Camera gets stuck when trying to go past its set limits

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

I have a script that uses translate() to move the camera with the mouse, and the camera is limited to a specific area of the level but when the camera reaches those limits and if the player where to try to move the camera beyond the limits, the camera gets a bit stuck when trying to move away from the limits.
Here is a video of the issue, sorry about the weird size or the capture I don’t know why it’s doing that: https://imgur.com/a/d1pnLZA

Thanks in advance.

:bust_in_silhouette: Reply From: aeh_keine_ahnung

This is because you dont limit the cameras position,
the camera itself is still moving beyond the limits but the viewport isnt.
try something like this:

position = Vector2(clamp(position.x,limit_left+get_viewport_rect().size.x/2,limit_right-get_viewport_rect().size.x/2),clamp(position.y,limit_top+get_viewport_rect().size.y/2,limit_bottom-get_viewport_rect().size.y/2))

This will use the limits you gave the camera.

Hey thanks for this. I’m a beginner and found this comment of yours and it’s super helpful. Fixes my exact problem as well (the camera offset going past the limits). I’m struggling to understand your code though. I’m a beginner and it’s just a lot. haha can you help break it down?

bonsaipropaganda | 2023-04-15 17:24

Thanks for the Reply, i am happy to help :slight_smile:
I have broken the code down to make it more clear what is happening.
I also fixed an issue by now using global_position instead of position.

Use this code after you changed the position of the Camera2D
this code only works correctly when “Camera2D.anchor_mode” is Drag Center.

first we get the viewport size and divide it by 2 to get the viewport’s center.

var viewport_half_x = get_viewport_rect().size.x/2
var viewport_half_y = get_viewport_rect().size.y/2

then we offset the limits to acount for the viewport size

var new_limit_left = limit_left+viewport_half_x
var new_limit_top = limit_top+viewport_half_y
var new_limit_right = limit_right-viewport_half_x
var new_limit_bottom = limit_bottom-viewport_half_y

lastly, we clamp the Camera2D’s position between the new limits.

var new_x = clamp(global_position.x, new_limit_left,new_limit_right)
var new_y = clamp(global_position.y, new_limit_top,new_limit_bottom)

global_position = Vector2(new_x,new_y)

Final code written in an function:

func snap_in_limit():
	#this code only works correctly when "Camera2D.anchor_mode" is Drag Center.
	
	#first we get the viewport size and divide it by 2 to get the viewport's center.
	var viewport_half_x = get_viewport_rect().size.x/2
	var viewport_half_y = get_viewport_rect().size.y/2
	
	#we offset the limits to acount for the viewport size
	var new_limit_left = limit_left+viewport_half_x
	var new_limit_top = limit_top+viewport_half_y
	var new_limit_right = limit_right-viewport_half_x
	var new_limit_bottom = limit_bottom-viewport_half_y
	
	#clamp the Camera2D's position between the new limits.
	var new_x = clamp(global_position.x, new_limit_left,new_limit_right)
	var new_y = clamp(global_position.y, new_limit_top,new_limit_bottom)
	
	global_position = Vector2(new_x,new_y)

Feel free to ask if anything is unclear/not working properly.

aeh_keine_ahnung | 2023-04-16 11:36

1 Like

Hey, I know it’s been a long time, so I’m not sure if you’re checking this. But I’ve tried your code and it works, but only as long as I don’t zoom. Do you have any idea how this could be adapted to zoom?

The distance from the center of the camera to the limits is incorrect if the current zoom level is not 1. Therefore, the center of the viewport must be scaled up/down with the current zoom.

Scaled viewport center:

#scaled center of the viewport 
var viewport_half_x = get_viewport_rect().size.x/2 * (1 / zoom.x)
var viewport_half_y = get_viewport_rect().size.y/2 * (1 / zoom.y)

you’re a life saver… that took so many hours to debug and the fix was very simple too… Well, thank you so much