extends Camera2D class_name GameCamera @export var key : bool = true @export var drag : bool = true @export var edge : bool = false @export var wheel : bool = true @export var zoom_in_limit : float = 2.5 # The max vector2 zoom value @export var camera_speed : int = 450 # Camera speed in px/s @export var camera_margin : int = 50 # Pixels around edge of screen where the mouse will start moving the camera # Initial zoom value taken from Editor. var camera_zoom : Vector2 = zoom const camera_zoom_speed = Vector2(0.5, 0.5) var camera_movement : Vector2 = Vector2.ZERO var _prev_mouse_pos : Vector2 = Vector2.ZERO # INPUTS # Right mouse button was or is pressed. var __rmbk : bool = false # Move camera by keys: left, top, right, bottom. var __keys : Array[bool] = [false, false, false, false] func _ready() -> void: set_drag_horizontal_enabled(false) set_drag_vertical_enabled(false) set_position_smoothing_enabled(true) set_position_smoothing_speed(4) func _physics_process(delta : float) -> void: # Move camera by keys defined in InputMap (ui_left/top/right/bottom). if key: if __keys[0]: camera_movement.x -= camera_speed * delta if __keys[1]: camera_movement.y -= camera_speed * delta if __keys[2]: camera_movement.x += camera_speed * delta if __keys[3]: camera_movement.y += camera_speed * delta # Move camera by mouse, when it's on the margin (defined by camera_margin). if edge: var rec : Rect2 = get_viewport().get_visible_rect() var v : Vector2 = get_local_mouse_position() + rec.size/2 if rec.size.x - v.x <= camera_margin: camera_movement.x += camera_speed * delta if v.x <= camera_margin: camera_movement.x -= camera_speed * delta if rec.size.y - v.y <= camera_margin: camera_movement.y += camera_speed * delta if v.y <= camera_margin: camera_movement.y -= camera_speed * delta # When RMB is pressed, move camera by difference of mouse position if drag and __rmbk: camera_movement = _prev_mouse_pos - get_local_mouse_position() # If this movement would take us out of clamp we don't want to do it: var position_change : Vector2 = camera_movement * get_zoom() if (position.x + position_change.x) < limit_left or\ (position.x + position_change.x) > limit_right: camera_movement.x = 0 if (position.y + position_change.y) < limit_top or\ (position.y + position_change.y) > limit_bottom: camera_movement.y = 0 if camera_movement.y != 0 or camera_movement.x != 0: # Update position of the camera. position += camera_movement * get_zoom() # Set camera movement to zero, update old mouse position. camera_movement = Vector2(0,0) _prev_mouse_pos = get_local_mouse_position() func _unhandled_input( event : InputEvent) ->void: if event is InputEventMouseButton: var mouse_event : InputEventMouseButton = event as InputEventMouseButton if drag and\ mouse_event.button_index == MOUSE_BUTTON_RIGHT: # Control by right mouse button. if mouse_event.pressed: __rmbk = true else: __rmbk = false # Check if mouse wheel was used. Not handled by InputMap! if wheel: if mouse_event.button_index == MOUSE_BUTTON_WHEEL_DOWN and\ camera_zoom.x - camera_zoom_speed.x > 0 and\ camera_zoom.y - camera_zoom_speed.y > 0: camera_zoom -= camera_zoom_speed set_zoom(camera_zoom) if mouse_event.button_index == MOUSE_BUTTON_WHEEL_UP and\ camera_zoom.x + camera_zoom_speed.x < zoom_in_limit and\ camera_zoom.y + camera_zoom_speed.y < zoom_in_limit: camera_zoom += camera_zoom_speed set_zoom(camera_zoom) # Control by keyboard handled by InpuMap. if event.is_action_pressed("ui_left"): __keys[0] = true if event.is_action_pressed("ui_up"): __keys[1] = true if event.is_action_pressed("ui_right"): __keys[2] = true if event.is_action_pressed("ui_down"): __keys[3] = true if event.is_action_released("ui_left"): __keys[0] = false if event.is_action_released("ui_up"): __keys[1] = false if event.is_action_released("ui_right"): __keys[2] = false if event.is_action_released("ui_down"): __keys[3] = false