extends Node3D @export_category("Speed") @onready var move_speed: float = ProjectSettings.get_setting("game/controls/camera_move_speed",20.0) @onready var zoom_speed: float = ProjectSettings.get_setting("game/controls/camera_zoom_speed",20.0) @export_category("Limits") @export_range(-10,10,1) var zoom_min: float = -8 @export_range(11,50,1) var zoom_max: float = 20 @export_range(0,0.95,0.01) var zoom_speed_damp: float = 0.5 @export_range(0,32,4) var edge_scrolling_margin: int = ProjectSettings.get_setting("game/controls/edge_scrolling_margin",8) @onready var edge_scrolling_speed: float = ProjectSettings.get_setting("game/controls/edge_scrolling_speed",25.0) @onready var socket: Node3D = $camera_point @onready var cam : Camera3D = %camera_player var zoom_direction : float = 0.0 ## 0.0 means no zoom. Use 1.0 for moving toward the floor var move_disabled:bool = false var zoom_disabled:bool = false var edge_scroll_disabled:bool = ProjectSettings.get_setting("game/controls/edge_scrolling_disabled",false) # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta: float) -> void: cam_move(delta) cam_zoom(delta) cam_edge_scroll(delta) func _unhandled_input(event: InputEvent) -> void: if event.is_action("scroll_up"): zoom_direction = -1 if event.is_action("scroll_down"): zoom_direction = 1 ## Controls the movement of the player camera func cam_move(delta:float) -> void: if move_disabled:return var velocity_direction := Vector3.ZERO if Input.is_action_pressed("cam_backward"): velocity_direction -= transform.basis.x if Input.is_action_pressed("cam_forward"): velocity_direction += transform.basis.x if Input.is_action_pressed("cam_left"): velocity_direction -= transform.basis.z if Input.is_action_pressed("cam_right"): velocity_direction += transform.basis.z position += velocity_direction.normalized() * delta * move_speed * get_zoom_factor() ## Controls the zoom of the player camera ## [br] ## [param zoom_direction] control the direction. ## 0.0 means no zoom. Use 1.0 for moving toward the floor func cam_zoom(delta:float) -> void: if zoom_disabled:return var new_zoom: float = clamp(cam.position.z + zoom_speed * zoom_direction * delta,zoom_min,zoom_max) print(new_zoom) cam.position.z = new_zoom zoom_direction *= zoom_speed_damp #Smooth the deceleration func get_mouse_position() -> Vector2: return get_viewport().get_mouse_position() ## multiplicator for movement speed, based on zoom level func get_zoom_factor() -> float: return remap(cam.position.z,zoom_min,zoom_max,0.1,2.0) func cam_edge_scroll(delta:float) -> void: if edge_scroll_disabled:return var current_viewport = get_viewport() var pan_direction := Vector2(0,0) #Edge scrolling to bottom left by default, changing that if needed var viewport_rectange := Rect2i(current_viewport.get_visible_rect()) var viewport_size := viewport_rectange.size var mouse_position = get_mouse_position() # X PAN if (mouse_position.x < edge_scrolling_margin or (mouse_position.x > viewport_size.x - edge_scrolling_margin)): pan_direction.x = 1 if (mouse_position.x > viewport_size.x/2) else -1 # detect if we are in the half of the screen or not # Y PAN if (mouse_position.y < edge_scrolling_margin or (mouse_position.y > viewport_size.y - edge_scrolling_margin)): pan_direction.y = 1 if (mouse_position.y < viewport_size.y/2) else -1 # detect if we are in the half of the screen or not var pan_vector:= Vector2(pan_direction.x,pan_direction.y) * delta * edge_scrolling_speed * get_zoom_factor() translate_object_local(Vector3(pan_vector.y,0,pan_vector.x))