• Godot HelpGUI
  • How to make a control node ignore Window Stretch Mode

I was having difficulty getting my game UI to scale based on the screen size, at higher resolutions, the UI elements got really small. That's where I found that I could set the window stretch mode in Project Settings to "canvas_layer". This seems to work great, as I lay out my UI, the ratios and sizes look the same no matter what display it is on. Here is the issue, I have a UI element for a reticle that has lines that are 2px thick. However in fullscreen mode, now those lines are very thick. How can I keep those 2px thick no matter what?

    kuligs2 Yes I did, the stretch mode is working as I expect it to, however it applies to all canvas items. There is no way as far as I can tell to also have some canvas elements keep pixel width with this stretch mode enabled.

    jrlowe24 this is very simple, put your sight inside a window node, then you can change the stretch mode for the window only.
    alternatively, set the game to a strech mode for the sight, and then put your UI inside a window.

      Jesusemora This doesn't really satisfy the requirements though, while this would let me not scale up the reticle, the spacing and layout that I set my reticle (and move it since it's dynamic), needs to scale as well, however it is the line thickness that I need to keep at 2px. If I just put it in a window with no stretch mode, on a very large screen, the reticle would be tiny in the middle, rather than scaling the distances accordingly. Also, I don't think you can simply just have a window within the main window, It renders an extra actual window when I do this

        jrlowe24 while this would let me not scale up the reticle, the spacing and layout that I set my reticle (and move it since it's dynamic), needs to scale as well, however it is the line thickness that I need to keep at 2px.

        I suppose, purely in theory, that one could try to draw with code. That is, the place for the reticle frame changes according to the resolution, and the mark itself is drawn from the code and its thickness is set there and saved regardless of the size.

        jrlowe24 I tested my theory and could not get it to work, window has too many options but none that could be set without requiring code.

        jrlowe24 This doesn't really satisfy the requirements though, while this would let me not scale up the reticle, the spacing and layout that I set my reticle (and move it since it's dynamic), needs to scale as well, however it is the line thickness that I need to keep at 2px. If I just put it in a window with no stretch mode, on a very large screen, the reticle would be tiny in the middle, rather than scaling the distances accordingly.

        I found an option in project settings window, called scale. it lets you give a scale to the elements. you also have the "snap mode", you can set to integer to snap to the pixels.
        how are you changing window size? you could do some very simple math and manually scale the sight node based on the new resolution compared to the default.

        like if your window width is 960 by default, and the new res is 1920, you could do something like 1.0/960 * 1920

        var default_resolution = Vector2(960, 540)
        var new_resolution = Vector2(1920, 1080)
        var n_scale : float = Vector2(1.0/(1.0/default_resolution.x*new_resolution.x), 1.0(1.0/default_resolution.y*new_resolution.y))
        reticle.scale = n_scale

        this would scale your reticle to 1-1 pixels.
        you could also check the resolution and multiply by a value, like at 4k you could multiply by 4 to make it bigger. you could make this easier by setting up a Curve resource (@export var curve : Curve) and using sample to get each value (curve.sample(0.5)).

        Supposedly, theoretically, there is another way. Set the size of the aiming mark in pixels. So that at different resolution and window size the size of the sight by pixels would be the same. But to calculate the size, probably, will not be very easy.

          Tomcat with control nodes you can make it automatic. no need to code.
          the only problem would be text size since it can't be scaled.

            Jesusemora the only problem would be text size since it can't be scaled.

            Maybe I don't understand very well because of the translation, but I didn't see anything about the text here — just the reticle.

            jrlowe24 the reticle would be tiny in the middle

            Tomcat Supposedly, theoretically, there is another way. Set the size of the aiming mark in pixels. So that at different resolution and window size the size of the sight by pixels would be the same.

            Tomcat But to calculate the size, probably, will not be very easy.

            here is how the UI works: the main window has a stretch mode that can be nothing, canvas_items, or ugly af.
            nothing means the UI is kept 1-1. it looks small in 4k.
            canvas_items means the UI is scaled to the window size and can retain some proportion. reticle is too big.
            the last one is not worth talking about.

            in order to make the reticle 1-1 the window would have to be set to nothing, otherwise it would be scaled. the problem is the GUI that remains at a small size.

            well, Controls have containers that can automatically resize to cover a percentage of the screen, so you could make a UI that stays the same size regardless of screen size, as they divide the screen into sections.
            the only problem is text, because it follows the font size, but maybe there is a way.

              Jesusemora the only problem is text, because it follows the font size, but maybe there is a way.

              Make two layers: one with the font scaled, the other with the mark tied to the pixel size. The main thing is that they should be match.

              This should be tried, prototyped.

              jrlowe24 How do I tie it to the pixel size?

              In brief, it's a problem. One that needs to be studied. I can only assume for now that you need to take the window size in pixels screen_get_size and calculate it.