Godot 3 to 4 rename
VisibilityNotifier3D in Godot 4: it is VisibleOnScreenNotifier3D now
VisibilityNotifier3D is VisibleOnScreenNotifier3D in Godot 4.7.2, and the editor's parse error names it. Its screen_entered and screen_exited signals keep their names; connect them through the signal itself, notifier.screen_entered.connect(...).
What Godot prints
A Node3D that adds a VisibilityNotifier3D and connects its screen_entered signal the Godot 3 way.
extends Node3D
func _ready():
var notifier = VisibilityNotifier3D.new()
notifier.connect("screen_entered", self, "_on_screen_entered")
add_child(notifier)
func _on_screen_entered():
print("on screen")
SCRIPT ERROR: Parse Error: Identifier "VisibilityNotifier3D" not declared in the current scope. Did you mean to use "VisibleOnScreenNotifier3D"?
at: GDScript::reload (res://answers/visibilitynotifier3d-in-godot-4/repro.gd:4)
ERROR: Failed to load script "res://answers/visibilitynotifier3d-in-godot-4/repro.gd" with error "Parse error".
at: load (modules/gdscript/gdscript_resource_format.cpp:46)The fix
The same notifier as VisibleOnScreenNotifier3D, its signals connected through the Signal objects. The fix prints the class and its default box.
extends Node3D
func _ready() -> void:
var notifier := VisibleOnScreenNotifier3D.new()
notifier.screen_entered.connect(_on_screen_entered)
notifier.screen_exited.connect(_on_screen_exited)
add_child(notifier)
print(notifier.get_class(), " aabb: ", notifier.aabb)
func _on_screen_entered() -> void:
print("on screen")
func _on_screen_exited() -> void:
print("off screen")
VisibleOnScreenNotifier3D aabb: [P: (-1.0, -1.0, -1.0), S: (2.0, 2.0, 2.0)]Why it happens
GDScript's analyzer resolves every identifier when the script loads. VisibilityNotifier3D is not a class in Godot 4.7.2, so the script fails to parse and Godot does not load it. The editor build adds the new name from Godot's 3 to 4 rename table: Did you mean to use "VisibleOnScreenNotifier3D"?
The table maps both VisibilityNotifier, the 3D node's Godot 3 name, and VisibilityNotifier3D to VisibleOnScreenNotifier3D, and VisibilityNotifier2D to VisibleOnScreenNotifier2D.
Godot 3.6's VisibilityNotifier also had camera_entered and camera_exited signals and a max_distance property. VisibleOnScreenNotifier3D has screen_entered, screen_exited and its bounding box, aabb, which the fix printed at its default: a 2 by 2 by 2 box centred on the node.
Object.connect() in Godot 4 takes the signal's name and a Callable, not a target object and a method name, so the Godot 3 call connect("screen_entered", self, "_on_screen_entered") does not carry over as written. The fix connects through the Signal object instead.
Sources
- renames_map_3_to_4.cpp line 1626, VisibilityNotifier3D to VisibleOnScreenNotifier3D
- renames_map_3_to_4.cpp lines 1624 and 1625, VisibilityNotifier and VisibilityNotifier2D
- gdscript_analyzer.cpp line 4687, the error with the rename hint
- VisibleOnScreenNotifier3D class reference
- VisibilityNotifier at 3.6-stable, its signals and max_distance
- Object.connect in the class reference
Run on Godot 4.7.2, .