How to check if a Camera2d reached its limits?

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

Hi!
My first project on Godot involves a region map consisting of hex tiles. I worked out how to build the grid dynamically and everything works well so far, but I’m stuck with the camera.
The player will be able to pan through the entire map with a mouse button. I managed to set the limits with information from the grid and I can’t visually move the camera beyond them. The code:

if event is InputEventMouseButton:
    if event.is_action_pressed("cam_drag"):
    isDragging = true
    checkPosition()
    if event.is_action_released("cam_drag"):
    isDragging = false

if event is InputEventMouseMotion and isDragging:
    position += event.relative * zoom.x * -1

The problem is: If I keep moving the mouse, even though the camera visually reached its limits and stopped moving, the camera’s position and global_position keep being updated, which causes a problem when I want to pan back on the opposite direction.
Is there any Camera2D method which returns if it reached or not its limits?

I’ve tried to check this with this method:

func checkPosition():
    if global_position.x > baseLimitRight: #baseLimitRight equals limit_right
        position = Vector2(baseLimitRight - SIDE_BAR_WIDTH - target.position.x - 25, position.y)
    if global_position.y > limit_bottom:
        position = Vector2(position.x, limit_bottom - target.position.y - 50)

The method fairly works when panning the camera back when the position and global_position get higher than the right and bottom limits, but I can’t get to work when the position goes below limit_left and limit_top.

PS: When the Camera2D is instantiated is created at the player sprite position, so (0,0) at target.position, but I’m free to pan the camera around after this.

Example:
A) When I just reached the Camera’s limit_left.x and when the panning stops, I get these values:

Pos: (-2901, -114) # position
Global: (1757, 1757) # global_position

B) If I keep moving the mouse to the left, the Camera doesn’t move at all, but I get these values:

Pos: (-16488, -111) # position
Global: (-11830, 1760) # global_position

Any idea how to tackle this situation?

Not sure if this is the best option but i would clamp the position of the camera within the move function by checking if the camera is within the range before allowing it to move, something like this:

if event is InputEventMouseMotion and isDragging:
    if abs(position.x) < max_x and abs(position.y) < max_y:
        position += event.relative * zoom.x * -1

this is assuming the max x and y are equidistant from the origin, if they are not, you could just check the negative values individually, like this:

if event is InputEventMouseMotion and isDragging:
    if min_x < position.x < max_x and min_y < position.y max_y:
        position += event.relative * zoom.x * -1

osimmac | 2020-04-07 17:32

I’ve already tried this approach, but once the camera is off-range, it gets stuck as the condition will never be true again for it to move.
But thanks anyways!

lsgrandchamp | 2020-04-08 04:10

of course! im silly, what about if you were to check not its current position, but what its position would be if you were to move it?

if event is InputEventMouseMotion and isDragging:
    var nextpos = position + event.relative*zoom.x*-1
    if min_x < nextpos.x < max_x and min_y < nextpos.y max_y:
         position += event.relative * zoom.x * -1

i have no idea if this will work, but i think it would avoid moving the camera out of range.

osimmac | 2020-04-08 04:43

Perfect! It worked!
I finally got the camera working properly, thank you osimmac!
Now I need to figure out how to set your comment as this question answers.
One little thing though, I had to write the if statment as follows:

if nextPos.x > minX and nextPos.x < maxX and nextPos.y > minY and nextPos.y < maxY:

With your statement, I got the error: Invalid operands 'bool' and 'float' in operator '<'

lsgrandchamp | 2020-04-09 15:01

I’m experiencing the exact same thing and I’m pretty sure this is a BUG! If I have to clamp the camera position (global_position) to its limits manually, then there is no reason to have those limits in the first place.

R0AR | 2020-04-11 06:51

LOL still happening in Godot3.3.2

pengyou | 2021-09-11 10:55