Setting SubViewport mask programmatically

Godot Version

v4.2.2.stable.official [15073afe3]


I have a popup Node2D that I want to show over my current UI. I designed it so the popup is a different scene.

As this is a simple project, initially I had z-indexing and was using visible = true to simply show it over my other screen elements.

However, i saw “visibility layers” are a thing, so I can remove the janky visible flags all over my code if there is a way to set SubViewport mask programmatically.

This also gives me a faster debug route as I can just toggle the masks in the 2d view. However, i can’t see an int array property for the masks.

Please assist, but only because I refactored things before i checked it was possible.

Ok, so what I need is Viewport’s

void set_canvas_cull_mask_bit(layer: int, enable: bool)
…which allows individually toggling a level’s visibility.

But i find the doc hard to read. The method suggests setting a mask bit, but the parameter is named “layer”. Also, given the below wording:

Set/clear individual bits on the rendering layer mask. This simplifies editing this Viewport's layers.

Doesn’t help to explain the enable flag. My understanding of mask is that if I want layers 2 (Bit 1, value 2) and 3 (bit 2, value 4) to show, I could just send a single 6 is as a param, and this tells us we want layers 2 and 3 (values 2 + 4). Setting 0 would clear them all.

On testing it appears “level” is correct and the method is badly named. If I set (1, true) only my Layer 2 is shown (Bit 1, value 2).
It also doesn’t unset other levels, like I thought a mask would.

There is also no array input, so if I want to enable or disable multiple layers at once, I can’t, I have to individually set each to on or off.

Possible enhancement?

Anyway. the answer is to directly use the mask property
canvas_cull_mask which semi-works as I would expect.

canvas_cull_mask = 0 will show my Layer 1.
canvas_cull_mask = 1 will show my Layer 2.
canvas_cull_mask = 3 will show both.

So still not using the “bit” of the layers, but it masks my layer number.

Also didn’t help that I had an await method not waiting, but that’s programmer error and unrelated to the above :slight_smile: