class_name Camera extends Camera2D signal zoomed(zoom: Vector2) var is_in_drag_mode = false var drag_anchor = Vector2.ZERO @export var speed = 25 @export_group("Zoom", "zoom") @export var zoom_min: float = 0.5 @export var zoom_max: float = 3 @export var zoom_step: float = 0.01 func _ready(): get_viewport().size_changed.connect(func(): set_new_position(global_position) var new_zoom = Vector2( (limit_right - limit_left) / get_viewport_rect().size.x, (limit_bottom - limit_top) / get_viewport_rect().size.y ) zoom = Vector2( new_zoom[new_zoom.max_axis_index()], new_zoom[new_zoom.max_axis_index()] ) zoomed.emit(zoom) ) func _input(event): if event.is_action("camera_zoom_out"): var can_zoom_out = ( (limit_right - limit_left) / get_rect().size.x > 1.0 and (limit_bottom - limit_top) / get_rect().size.y > 1.0 ) if can_zoom_out: var new_zoom = max(zoom.x - zoom_step, zoom_min) zoom = Vector2(new_zoom, new_zoom) zoomed.emit(zoom) if event.is_action("camera_zoom_in"): var new_zoom = min(zoom.x + zoom_step, zoom_max) zoom = Vector2(new_zoom, new_zoom) zoomed.emit(zoom) if event.is_action_pressed("camera_drag"): is_in_drag_mode = true drag_anchor = get_global_mouse_position() elif event.is_action_released("camera_drag"): is_in_drag_mode = false func _process(delta): if is_in_drag_mode: set_new_position(global_position + drag_anchor - get_global_mouse_position()) var direction_h = Input.get_axis("ui_left", "ui_right") var direction_v = Input.get_axis("ui_up", "ui_down") if direction_h != 0 or direction_v != 0: set_new_position( lerp( global_position, global_position + Vector2(direction_h * speed, direction_v * speed), speed * delta ) ) func set_new_position(new_position: Vector2): new_position.x = clamp( new_position.x, limit_left, limit_right - get_rect().size.x ) new_position.y = clamp( new_position.y, limit_top, limit_bottom - get_rect().size.y ) global_position = new_position func set_center(center_position: Vector2): set_new_position( center_position - (get_rect().size / 2) ) func get_rect(): var viewport = get_viewport_rect() return Rect2( global_position, viewport.size * Vector2(1 / zoom.x, 1 / zoom.y) )