Found my own implementation for colored aspect bars:
Scene structure:
The script (it replicates canvas item resizing with aspect keep. But adapting it for pixel games should be possible):
class_name BlackBars
extends MarginContainer
@export var color := Color.BLACK
@onready var __base_size := Vector2(
ProjectSettings.get_setting("display/window/size/viewport_width"),
ProjectSettings.get_setting("display/window/size/viewport_height"),
)
@onready var __oversampling: bool = ProjectSettings.get_setting("gui/fonts/dynamic_fonts/use_oversampling", true)
# Layer used for custom drawing the bars. You could also just change the bg color. This script originated from a version without subviewport. Were drawing above the scene was important.
@onready var __layer := CanvasLayer.new()
@onready var __base := Control.new()
func _ready() -> void:
%SubViewport.size_2d_override = __base_size
if __oversampling:
# Handled by this script
ProjectSettings.set_setting("gui/fonts/dynamic_fonts/use_oversampling", false)
add_child(__layer, false, Node.INTERNAL_MODE_BACK)
__layer.layer = 120
__layer.add_child(__base)
__base.set_anchors_preset(Control.PRESET_FULL_RECT, true)
__base.mouse_filter = Control.MOUSE_FILTER_IGNORE
__base.draw.connect(__draw_black_bars)
func __draw_black_bars() -> void:
if (__oversampling):
var factor = %SubViewport.size.x / __base_size.x
TextServerManager.get_primary_interface().font_set_global_oversampling(factor)
propagate_call(&"queue_redraw")
var aspect: float = __base_size.x / __base_size.y
if size.x / size.y > aspect:
var bar_width: float = (size.x - aspect * size.y) / 2.0
add_theme_constant_override(&"margin_left", bar_width)
add_theme_constant_override(&"margin_right", bar_width)
add_theme_constant_override(&"margin_top", 0)
add_theme_constant_override(&"margin_bottom", 0)
# Scaling of the viewport is handled by the margins. You could use anything to draw the bars. (e.g. textures or custom scenes)
__base.draw_rect(Rect2(0, 0, bar_width, size.y), color)
__base.draw_rect(Rect2(size.x - bar_width, 0, bar_width, size.y), color)
elif size.x / size.y < aspect:
var bar_height: float = (size.y - size.x / aspect) / 2.0
add_theme_constant_override(&"margin_top", bar_height)
add_theme_constant_override(&"margin_bottom", bar_height)
add_theme_constant_override(&"margin_left", 0)
add_theme_constant_override(&"margin_right", 0)
__base.draw_rect(Rect2(0, 0, size.x, bar_height), color)
__base.draw_rect(Rect2(0, size.y - bar_height, size.x, bar_height), color)