Gameplay Camera

Goals

Handle transition from level to level, camera effects like zoom and shake. It also handles navigation through multi screen levels as well as notifying game when level coordinates change inside a multi screen level.

How it works

Setting the camera to levels and level transitions

The Gameplay Camera lives inside LinearWorld and ProceduralWorld and is mostly controlled by them. It has two public functions they can use to set the camera to the initial level of a chunk/world and to move the camera between levels, and two other methods to toggle camera following the player on/off. All of these are being called automatically either in the world initialization or when transitioning between levels.

The GameplayCamera uses SceneTreeTween instead of normal Tween as its animations are simple, and SceneTreeTween is more modern and lightweight and compatible with the updated Tween API in Godot 4.x. Once it's 'move camera' tween ends, it emits the signal tweened_to_next_room so that LinearWorld or ProceduralWorld can continue handling the level transition from there.

Whenever we transition between levels, besides moving the camera, we also set the limits of the camera to the limits of the current level. This is not strictly necessary for single screen levels, but it makes working with multi screen levels easier and seamless.

On multi screen levels, the camera follow the player and emits the Events signal internal_level_coords_changed whenever the player moves to a new level coordinate.

The camera has a CameraAnchorDetector Area2D, which will handle locking the camera whenever it enters a CameraAnchor area. For more details about how to set up CameraAnchor nodes in multi screen levels, see Multi Screen Levels page.

The way they work overall is that CameraAnchorDetector calculates the level coordinate based on the CameraAnchor position, and then changes the limits of the GameplayCamera as if it was a single screen level at that coordinate. Once the player leaves the CameraAnchor, it restores the base limits of the level.

Zoom

They also are connected to two Events signals which control it's zoom level:

  • camera_zoomed
  • camera_zoom_reset

It is currently used for the Zoom in/out effect when entering/exiting a Pond.

Camera Shake

There is no way to control the camera shake directly, but whenever the player takes damage and the Event player_taken_damage is emitted, the Camera will shake based on the amount of damage inflicted.

With what script it communicates

It communicates directly with the CameraAnchorDetector which is its child, and mostly with Procedural/LinearWorld as they use the camera directly when setting up the world and when transitioning level, and their respective LevelChunkCoordinators as they handle moving between chunks.

Narrative scenes scripts may use move_camera like Part001_Tutorial for very specific and scripted sequences, while other scripts communicate with it either through sending Events or listening to its signals/Events.