Godot 4 courses Launching in Early Access starting Jan 30
you can now pre-order
godot 4 courses
Save up to 25%

Godot Nodes 101: VisibilityNotifier and VisibilityEnabler 2d

beginner

By: Henrique Campos - May 17, 2019

In this Godot tutorial, Pigdev shows you how to react to easily detect when a node enters or leaves the screen with the built-in Visibility Notifier and Visibility Enabler nodes.

So, what do you think is located on the other side of this wall?

There’s nothing. The graphics for backgrounds that can’t be seen by players are not rendered in order to save processing power.

In this dialogue from .hack//Rebirth, Ovan and Yata have a discussion similar to the philosophical question known as if a tree falls in a forest.

In games, we want to avoid processing objects that players can’t interact with, for example, when they’re off-screen.

In Godot, we can use visibility nodes to detect when an object is inside the player’s screen or viewport.

There are two types:

  1. VisibilityNotifier. It emits signals when a node enters or exits the view.
  2. VisibiltiyEnabler, which extends the VisibilityNotifier. It can automatically toggle processing on a parent node when it enters or leaves the view.

Let’s look at what each allows you to do.

To follow along, you can download our demo project in the Godot mini-tutorials repository. You’ll find the demo for this tutorial in the 2d/visibility-nodes folder.

Destroying projectiles outside the view

When firing a bullet, usually, it doesn’t have any use after it leaves the screen. Because this often means the player missed the target, especially on scroller games like jump ‘n’ shoots and space shooters.

We can free projectiles when they leave the view. For that, we can attach a VisibilityNotifier2D and connect its screen_exited signal to the projectile script. In the callback function, we can call queue_free() to destroy the node.

VisibilityNotifier2D signal connection

Here’s a bullet script that moves a virtual bullet in a straight line and destroys it when it leaves the view.

# Virtual bullet, we don't handle collisions here.
class_name Bullet
extends Node2D

export var speed := 800.0


func _physics_process(delta: float) -> void:
	var velocity := Vector2.RIGHT.rotated(rotation) * speed
	translate(velocity * delta)


func _on_VisibilityNotifier2D_screen_exited() -> void:
	queue_free()

Notice how the VisibilityNotifier2D displays as a pink rectangle inside the editor. It’s the notifier’s bounding-box. Godot uses it to check if the node entered or exited the view’s bounds.

Adjust this rectangle to control when the object is within or outside the view. If even a small part of the bounding box is inside the view, the notifier considers it’s “visible”. It will only emit the view_exited signal when the entire rectangle leaves the view.

VisibilityNotifier2D visibiltiy rectangle

With that, whenever a Bullet leaves the screen, it’s going to be automatically freed from memory.

Toggling AI agents on and off

Let’s say you want enemies to stop chasing the player if they’re outside the player’s view. Or maybe you only want it to start an attack pattern when the player can see it.

For that, we can use a VisibilityEnabler2D.

VisibilityEnabler2D is a specialized version of the VisibilityNotifier2D that automatically toggles processing on its parent node.

For instance, in our project’s DemoEnabler scene, we have some enemies that move in circles using a Path2D, a PathFollow2D, and an AnimationPlayer.

DemoEnabler Enemy’s Scene Tree

The animation interpolates the PathFollow2D > unit_offset property looping from 0.0 to 1.0.

Enemy’s fly animation

Now we can attach a VisibiltiyEnabler2D as a child of the Enemy. Usually, I turn on all the available options to prevent any behavior on the parent.

VisibilityEnabler2D settings

Notice that even animations can pause using this method without writing any code.

For testing purposes, we can attach a script on the Enemy and in the _process callback, print the Sprite’s global_position to test when the Enemy starts processing.

extends Path2D

func _process(delta: float) -> void:
	print($PathFollow2D/Sprite.global_position)

As you can see in the Output bottom panel, lines only appear when the VisibiltiyEnabler2D enters the screen.

These are the two main uses of the visibility nodes: emitting signals and toggling processing automatically. They come in handy in many situations and help you improve performance significantly, especially in large game levels.

For instance, you can use these notifiers to preload a next room or chunk of an open world when the player enters an area. In that, it’s an excellent alternative to the Area2D node.

There are many more cases you’ll find these nodes useful. Now, it’s up to you to use these new powers wisely!

Resources

01.visibility-notifier-signals.png 01.visibility-notifier-signals.png
02.visibility-rectangle.png 02.visibility-rectangle.png
03.visibility-enabler-enemy.png 03.visibility-enabler-enemy.png
04.enemy-animation.png 04.enemy-animation.png
05.visibiltiy-enabler-settings.png 05.visibiltiy-enabler-settings.png

Made by

Henrique Campos

Indie game developer and designer. I also like cooking.