Building HUD around the camera

Firstly, the conversation here was a mess, we need to clarify some concepts.

SubViewport inherits from Viewport, which is a fundamental enviornment for anything to be rendered. How? In fact Window actually inherits from Viewport, so everything are under a invisible Viewport. Even the editor itself puts everything under a SubViewport node to render your scene editing view in realtime.

Your project settings related to the viewport were applied implicitly to that hidden Window (again, it inherits Viewport). And the SubViewport node separates its children from the main enviornments while fowarding those settings as if he’s the game.

The stretch mode (disabled, canvas_item, and viewport) are not a property of Viewport to be strict, they only determine how big the rendered image’s size are, and whether to fit it or stretch it. That’s why we use SubViewportContainer, it will display the render result from its child SubViewport, and surely you can decide whether to center it or stretch it etc. using the Control node’s layout properties.

In details, the SubViewport.size property indicates how big the rendered screen are, and SubViewportContainer.stretch decides whether to resize its child SubViewport’s size to its own size or not.

2 Likes

I have solved it without using subviewport.

  1. Build scene around your main resolution.
  2. Set global resolution higher to make room for UI around it.
  3. Create UI like you would always do, just position it around the camera.
  4. You can also move around the actual game node around, but it’s not straightforward. For some reason Godot ignores Node2D transforms. You have to transform Camera2D position. This doesn’t move the position of the camera, but moves around the game scene. And all of it just works.

This also bypasses the problem that subviewport ignores project settings, so pixel art rotates as expected.

The game you described has a fixed resolution, so directly place things at their position. CanvasLayer was made for rendering things that should stick with the screen, not the world. You said that Node2D’s transforms are not working, I wonder which node are you moving. Moving the camera of course will move the scene around as expected, it represents the camera after all. By the way, setting Camera2D.anchor_mode=FIXED_TOP_LEFT makes more sense.

1 Like