In this tutorial, you will learn to make a camera zoom smoothly in 2D using tween animation. We will code a camera that can zoom using the mouse wheel with a minimum and maximum zoom level.
You can find the full project here.
Setting up the Scene
First, we need to create a new scene with a Camera2D as its root. Name it ZoomingCamera2D and add a Tween node as a child.
In the Inspector, set the camera node as Current so Godot uses it as our game’s camera. The active camera is always the last one that set its
current property to
Below, you will see we have some input actions we defined in the Project -> Project Settings… -> Input Map. Three are related to movement and two map the mouse wheel button to zooming in and out.
Attaching the camera to a Player scene
We designed a player-controlled ship to test our camera for this small demo. It’s a
KinematicBody2D node with the following code attached to it:
# Ship that rotates and moves forward, similar to classics like Asteroid. class_name Player extends KinematicBody2D export var speed := 250 export var angular_speed := 2.0 func _physics_process(delta): # Calculation of the direction to rotate. var direction := Input.get_action_strength("right") - Input.get_action_strength("left") var velocity = Input.get_action_strength("move") * transform.x * speed rotation += direction * angular_speed * delta move_and_slide(velocity)
Finally, to get the camera and its zoom centered in the Player, the ZoomingCamera2D should be a child of our Player.
Coding the zoom
Attach a new script to ZoomingCamera2D. Let’s define some properties to control the camera’s zoom range and speed.
class_name ZoomingCamera2D extends Camera2D # Lower cap for the `_zoom_level`. export var min_zoom := 0.5 # Upper cap for the `_zoom_level`. export var max_zoom := 2.0 # Controls how much we increase or decrease the `_zoom_level` on every turn of the scroll wheel. export var zoom_factor := 0.1 # Duration of the zoom's tween animation. export var zoom_duration := 0.2 # The camera's target zoom level. var _zoom_level := 1.0 setget _set_zoom_level # We store a reference to the scene's tween node. onready var tween: Tween = $Tween
Let’s look at
_zoom_level’s setter function next. We use it to trigger the tween animation and smoothly zoom in and out.
func _set_zoom_level(value: float) -> void: # We limit the value between `min_zoom` and `max_zoom` _zoom_level = clamp(value, min_zoom, max_zoom) # Then, we ask the tween node to animate the camera's `zoom` property from its current value # to the target zoom level. tween.interpolate_property( self, "zoom", zoom, Vector2(_zoom_level, _zoom_level), zoom_duration, tween.TRANS_SINE, # Easing out means we start fast and slow down as we reach the target value. tween.EASE_OUT ) tween.start()
Finally, we use the
_unhandled_input() callback to update the camera’s zoom level, using the input actions defined earlier. Notice how the
Camera2D.zoom value zooms in when it becomes smaller and zooms out when it increases.
func _unhandled_input(event): if event.is_action_pressed("zoom_in"): # Inside a given class, we need to either write `self._zoom_level = ...` or explicitly # call the setter function to use it. _set_zoom_level(_zoom_level - zoom_factor) if event.is_action_pressed("zoom_out"): _set_zoom_level(_zoom_level + zoom_factor)
Our tutorials are the result of careful teamwork to ensure we produce high quality content. The following team members worked on this one: