Check out the source code. If you do, make sure to use the latest Godot 4 version!
In this blog post we will recreate this look in godot:
The base game scene we are working with, looks like this:
It can be anything you want really - I chose to build a basic boat on water. ⛵️🌊
Important to note though - set your stretch mode to
Our “container scene” basically just holds both our UI and our Game:
The whole trick is setting the
TextureRect texture to a
new ViewportTexture and when it asks you to select a Subviewport, you pick the
SubviewPort that contains your main gameplay scene from before.
Because I’ve found some buggy behaviour when attaching the
GameTextureRect - and that’s how it’s supposed to be - you can set the texture at runtime as a workaround. The error only occurs when the texture is set in the editor. This way we don’t set it, but let gdscript take care of it for us:
# attach this script to the GameTextureRect extends TextureRect @onready var game_viewport = $GameViewport # Called when the node enters the scene tree for the first time. func _ready(): texture = game_viewport.get_texture() as ViewportTexture texture.set_viewport_path_in_scene("GameTextureRect/GameViewport")
I’ll keep an eye on the issue, as this should only be a beta-workaround.
Do whatever you want
TextureRect-Node needs two properties. First, we set it’s
Layout -> Anchors Preset to
Full Rect. And also, we need to set the
Texture -> Filter to
After we can resize our game’s resolution however we like:
TextureRect will scale it to fit our window dimensions, and produce a “pixelated” look!
Basically it makes our
1920x1080 game render through a
The main reason why you would use a
SubViewport, is because of the ability to have your whole UI on a separate layer.
You can also set the
Viewport Width/Height to a small size and use
Window Width/Height Override to make the actual window bigger - it will achieve the same look, but it will also upscale your UI and make it very hard to work with. Especially once you end up needing to make your
font_size = 2px. 🤔