## manages current scene and viewport scaling extends Node # methods of scaling viewport enum ScalingMode { INTEGER, # maintain aspect ratio and scale by whole numbers ASPECT, # maintain aspect ratio STRETCH, # stretch to fill screen } ## method used to scale game viewport export (ScalingMode) var scaling_mode: int = ScalingMode.INTEGER # node references # onready var viewport_container: ViewportContainer = $ViewportContainer onready var viewport: Viewport = $ViewportContainer/Viewport var resolution: Vector2 var current_scene: Node setget change_scene ## change the current scene func change_scene(new_scene: Node) -> void: # remove current scene if it exists if current_scene != null: viewport.remove_child(current_scene) current_scene.queue_free() # remove child from parent if it has one if new_scene.is_inside_tree(): new_scene.get_parent().call_deferred("remove_child", new_scene) # add new scene to tree viewport.call_deferred("add_child", new_scene) current_scene = new_scene func _ready() -> void: var tree := get_tree() # capture initial scene if tree.current_scene != self: change_scene(tree.current_scene) tree.current_scene = self # capture autoloads in the group "viewport_autoload" for node in tree.get_nodes_in_group("viewport_autoload"): node.get_parent().call_deferred("remove_child", node) viewport.call_deferred("add_child", node) # get design resolution from project settings var project_resolution := Vector2( ProjectSettings.get_setting("display/window/size/width"), ProjectSettings.get_setting("display/window/size/height") ) viewport.size = project_resolution resolution = project_resolution # size container and pivot on center viewport_container.rect_size = resolution viewport_container.rect_pivot_offset = resolution / 2.0 # fix viewportcontainer input bug viewport.set_deferred("handle_input_locally", true) # connect resized signal tree.connect("screen_resized", self, "_on_screen_resized") _on_screen_resized() func _process(delta: float) -> void: if Debug.entry == false: #CRT FILTER if Input.is_action_just_pressed("crt"): viewport_container.material.set_shader_param("enabled", not viewport_container.material.get_shader_param("enabled")) func _on_screen_resized() -> void: var screen_size := OS.window_size var scale_delta := screen_size / resolution match scaling_mode: ScalingMode.INTEGER: # find smaller scale difference, floor to integer var scale = floor(min(scale_delta.x, scale_delta.y)) viewport_container.rect_scale = Vector2(scale, scale) ScalingMode.ASPECT: # find smaller scale difference var scale = min(scale_delta.x, scale_delta.y) viewport_container.rect_scale = Vector2(scale, scale) ScalingMode.STRETCH: # simply use scale difference viewport_container.rect_scale = scale_delta