I’ve decided to use SubViewports, this is what I’ve got so far:
AspectRatioContainer (set `ratio` to `1.3333`)
└── SubViewportContainer (set `stretch` to `true`)
└── SubViewport
└── Sprite
It works for the most part, except for one issue: the CanvasItems inside the SubViewport do not scale properly. For I example, when I shrink the window, the canvas items should also shrink, but they do not.
How can I ensure that the sprite scales with the window size?
I’m trying to implement this into an already existing project and having to update all the UI to scale like that would be a massive pain. Sorry for the late reply! I forgot I made this post.
I did manage to get the effect I wanted but the method I used was super messy. Here’s the scene structure:
AspectRatioContainer (set `ratio` to `1.3333`)
└── SubViewportContainer (set `stretch` to `true`)
└── SubViewport
└── CanvasLayer (set `follow_viewport_enabled` to `true`)
└── SubViewportContainer (set `stretch` to `true`)
└── SubViewport
└── Sprite2D
then you need to attach this script to the parent of AspectRatioContainer:
extends Control
@onready var subviewport: SubViewport = $AspectRatioContainer/SubViewportContainer/SubViewport
@onready var canvas_layer: CanvasLayer = $AspectRatioContainer/SubViewportContainer/SubViewport/CanvasLayer
@onready var subsubviewportcontainer: SubViewportContainer = $AspectRatioContainer/SubViewportContainer/SubViewport/CanvasLayer/SubViewportContainer
func _process(_delta: float) -> void:
# Get the project window size
var width: int = ProjectSettings.get_setting(&"display/window/size/viewport_width")
var height: int = ProjectSettings.get_setting(&"display/window/size/viewport_height")
var window_size: = Vector2(width, height)
# Scale the canvas layer
canvas_layer.scale = Vector2(subviewport.size) / window_size
# Not sure what this does exactly but it fixes a weird window clipping bug.
subsubviewportcontainer.size = window_size*2.0