Hi! First time using this forum so excuse any misstakes I make in writing/categorising.
Like the title says, my Camera2D node has limits set up using the limit section in the inspector. The limits I’ve set are Right (640 + 250 = 890) and Left (-250) which should make panning possible 250 px to the right and left respectively(?). The project is running in 640x360.
The issue I’ve got is when I zoom out the camera. Now if both of the limits are set like above, then the camera limits properly to the right (the camera physically cant see more than 250 to the right) but can sadly keep zooming out infinitely in the left direction and ignores the left limit I’ve set completely. If I instead remove the right limit and set it to a large number, then the left limit works.
My issue is that I’d like it to stop being possible to zoom out if both limits are reached, right now only one limit works at a given time, with the right taking precedence for some reason over the left.
I code in GDScript. Here’s the simple code used for zooming the cam in and out:
The camera limits are a very basic implementation of the idea of not letting the camera move too far. This doesn’t really work when you have the ability to zoom. If you just clamp the camera position to be within the limits after you zoom, in your own code, it will work as you expect it. Just remember to take half the viewport size into account in your calculation.
Yes, that’s what I figured too and I tried to implement something like what you said but couldn’t get it to work at all sadly. I’d really appreciate code examples, quite new to Godot as a whole.
When I said post your script I meant post the whole file, from extends Camera2D to the end, because that makes it easier to give you a better answer, please.
I am not super confident this is what you need, but try it. =3
extends Camera2D
@export var zoomIncrement = 0.05
@export var zoomMin = 0.5
@export var zoomMax = 2.0
@export var panMaxRight = 10
@export var panMaxLeft = -10
@export var panMaxUp = -50
@export var panMaxDown = 50
# private vars for the corners of the limit area we set with the exported vars
var _panNW: Vector2
var _panSE: Vector2
var panning:= false
var zoom_level:= 1.0
var startPos
func _ready():
startPos = global_position.x
panMaxRight += startPos
panMaxLeft += startPos
_panNW = Vector2(panMaxLeft, panMaxUp)
_panSE = Vector2(panMaxRight, panMaxDown)
func _process(delta):
#zoomMin = #value betwen 0 - 1, res is 640, if zoom level 0.5 then "res" is 1280
#panMaxRight is 640 + 250 (890), ##panMaxLeft is -250
#640*(1+1-x) = 890 x = wantedMinZoom, x is btwen 0-1
#print((1 + 1-zoom.x) * 640)
pass
#if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):# and Input.is_key_pressed(KEY_CTRL):
# panning = true
# else:
# panning = false
#print(panning)
#func _input(event: InputEvent) -> void:
#if event is InputEventMouseButton: # Read Mouse Buttons
#print ("Mouse Button Event = ", event.as_text())
func _input(_event: InputEvent) -> void:
# get_tree().get_root() returns the same object as get_viewport() by default,
# but this is more correct if we ever use sub-viewports.
var viewport = get_viewport()
if _event is InputEventMouseButton:
match _event.button_index:
MOUSE_BUTTON_MIDDLE:
if _event.pressed:
panning = true
else:
panning = false
viewport.set_input_as_handled()
MOUSE_BUTTON_WHEEL_UP:
zoom_level = clamp(zoom_level + zoomIncrement, zoomMin, zoomMax)
zoom = zoom_level * Vector2.ONE
#print((1 + 1-zoom.x) * 640)
viewport.set_input_as_handled()
MOUSE_BUTTON_WHEEL_DOWN:
zoom_level = clamp(zoom_level - zoomIncrement, zoomMin, zoomMax)
zoom = zoom_level * Vector2.ONE
#Zooming out, if has zoomed out enough then cam limits will be hit!
#print((1 + 1-zoom.x) * 640)
limit_panning()
viewport.set_input_as_handled()
elif _event is InputEventMouseMotion and panning:
viewport.set_input_as_handled()
if panning:# and Input.is_key_pressed(KEY_CTRL):
# Panning rn
limit_panning()
else:
panning = false
func limit_panning():
# Just keep the camera position within the limits. clamp() on Vector2 worck component-wise.
position = clamp(position, _panNW, _panSE)
Hmm, that didn’t work, when panning to the max dist either direction the camera either snaps up or down from that far left/right position, and zoom is sadly like before where the limits are neglected.
I’m not really comfortable with that, I’ve got art that I wouldn’t want shared. If that means you can’t help further then I understand that. Is there anything else I can give to help? Camera2D is in position x 320 y 180, and has the posted script attached to it.
I finally solved it for anyone who finds this thread in the future.
What I ended up using was two “VisibleOnScreenNotifier2D” nodes that I then positioned via my script at the given panMaxLeft and panMaxRight respectively. I then referenced the two nodes in my camera script and used the inbuilt methods is_on_screen() to see when both of the nodes are on screen at the same time. If they are, then I shouldn’t be able to zoom out anymore. If only one node is on screen, then I shouldn’t be able to pan anymore toward that direction, and vice versa.
I did also set my camera limits on the left and right to be the panMaxLeft and panMaxRight, since the limits make it so that the camera sort of shifts toward the other direction if you try to zoom out whilst having hit a given limit. I hope this is helpful.