godotengine / godotengine/godot
VisibilityOnScreenEnabler2D Treats modulate values 0 and 1 as off-screen.
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
- Reproducable in 4.5.1.stable
- Unknown for other versions.
### System information
Godot v4.5.1.stable (f62fdbde1) - Windows 11 (build 26200) - Multi-window, 3 monitors - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3050 Ti Laptop GPU (NVIDIA; 32.0.15.8157) - 12th Gen Intel(R) Core(TM) i7-12700H (20 threads) - 31.67 GiB memory
### Issue description
Perhaps this is not a bug, and is intentional. However, I thought it was worth bringing up just in case.
Panning down the "modulate" property of a node to 0 or 1 in alpha triggers not-visible, firing the _on_visible_on_screen_enabler_2d_screen_exited() signal of VisibilityOnScreenEnabler2D (VOSE2D). A value of 0 may compute, but a value of 1 seems strange, as that is a non-zero visibility. A value of 2 does not trigger this. This says to me that instead of cutting "visibility" at a hard-zero value, Godot may have a threshold of alpha value that counts as not visible. If it is reading 1/255 = 0.0039 and 2/255 = 0.0078, perhaps the threshold is somewhere around 0.005.
### Steps to reproduce
- Have a scene with an attached script, a VisibilityOnScreenEnabler2D (VOSE2D) node, an AnimationPlayer node, a Camera2D node, and two other nodes that can be seen in a running game, like two Sprite2D's with different images loaded.
- In AnimationPlayer, create a blinking animation that toggles the visibility true/false property of the whole scene rapidly on discrete update mode for a short time when damage is taken or some other repeatable scenario.
- Position the Camera2D to make both Sprite2D'f fully visible in-game.
- Connect VOSE2D's "_on_visible_on_screen_enabler_2d_screen_exited()" to the scene script and have it queue_free() **just one** of the Sprite2D's in its function.
- Load the game and take damage or trigger the blink animation. See that the one Sprite2D frees when the first not-visible frame activates. This is typical, expected functionality.
- Change the visibility track in the animation to Modulate, toggling from 0 to 255, still on discrete update mode. Notice that the Sprite2D is freed again. This could still be seen as expected functionality, debatable.
- Change the toggling from 0 to 1, so that it is now switching between 1 and 255. Notice that again, the Sprite2D frees. This does not seem like expected functionality, IMO, as an alpha of 1 is visible.
- Change the toggling from 1 to 2, so that it is now switching between 2 and 255. The Sprite2D should not free, and instead partake in the blinking animation normally with the rest of the scene.
### Minimal reproduction project (MRP)
Easily repeatable.
Contributor guide
Research direction
Start by running the minimal reproduction with VisibilityOnScreenEnabler2D, AnimationPlayer, Camera2D, and the Sprite2D nodes described in the issue. Compare the screen-exited signal behavior for modulate alpha values 0, 1, 2, and 255. Done means the behavior is explained and, if unintended, the reproduction no longer frees the Sprite2D when alpha is 1.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- game-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100