## Scrolls the camera when the mouse cursor reaches the screen edge. ## Attach to a Camera2D node. Requires an OrthographicCamera2D or ViewportContainer ## to determine screen bounds at runtime. extends Camera2D ## Speed at which the camera scrolls (pixels per second). @export var scroll_speed: float = 400.0 ## Distance from the edge (in pixels) that triggers scrolling. @export var edge_margin: float = 40.0 ## Whether to clamp the camera position to a specific region. @export var clamp_enabled: bool = false ## Minimum bounds when clamping (in world space). @export var clamp_min: Vector2 = Vector2.ZERO ## Maximum bounds when clamping (in world space). @export var clamp_max: Vector2 = Vector2.ZERO var _screen_rect: Rect2 func _ready() -> void: _update_screen_rect() var viewport: Viewport = get_viewport() if viewport != null: viewport.size_changed.connect(_update_screen_rect) func _process(delta: float) -> void: if is_zero_approx(scroll_speed): return var mouse_pos: Vector2 = get_viewport().get_mouse_position() var scroll_dir: Vector2 = _get_scroll_direction(mouse_pos) if scroll_dir != Vector2.ZERO: position += scroll_dir * scroll_speed * delta if clamp_enabled: _clamp_position() func _get_scroll_direction(mouse_pos: Vector2) -> Vector2: var direction: Vector2 = Vector2.ZERO if mouse_pos.x < _screen_rect.position.x + edge_margin: direction.x -= 1.0 elif mouse_pos.x > _screen_rect.position.x + _screen_rect.size.x - edge_margin: direction.x += 1.0 if mouse_pos.y < _screen_rect.position.y + edge_margin: direction.y -= 1.0 elif mouse_pos.y > _screen_rect.position.y + _screen_rect.size.y - edge_margin: direction.y += 1.0 return direction.normalized() func _clamp_position() -> void: position.x = clampf(position.x, clamp_min.x, clamp_max.x) position.y = clampf(position.y, clamp_min.y, clamp_max.y) func _update_screen_rect() -> void: var viewport: Viewport = get_viewport() if viewport != null: _screen_rect = viewport.get_visible_rect()