Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Third-person camera with spring arm

Introduzione

3D games will often have a third-person camera that follows and rotates around something such as a player character or a vehicle.

In Godot, this can be done by setting a Camera3D as a child of a node. However, if you try this without any extra steps, you'll notice that the camera clips through geometry and hides the scene.

This is where the SpringArm3D node comes in.

Che cos'è un braccio a molla?

A spring arm has two main components that affect its behavior.

The "length" of the spring arm is how far from its global position to check for collisions:

../../_images/spring_arm_position_length.webp

The "shape" of the spring arm is what it uses to check for collisions. The spring arm will "sweep" this shape from its origin out towards its length.

../../_images/spring_arm_shape.webp

The spring arm tries to keep all of its children at the end of its length. When the shape collides with something, the children are instead placed at or near that collision point:

../../_images/spring_arm_children.webp

Braccio a molla con una telecamera

When a camera is placed as a child of a spring arm, a pyramid representing the camera will be used as the shape.

This pyramid represents the near plane of the camera:

../../_images/spring_arm_camera_shape.webp

Nota

Se al braccio a molla è assegnata una forma specifica, quella forma sarà sempre utilizzata.

La forma della telecamera è utilizzata solo se la telecamera è un figlio diretto del braccio a molla.

If no shape is provided and the camera is not a direct child, the spring arm will fall back to using a ray cast which is inaccurate for camera collisions and not recommended.

Every physics process frame, the spring arm will perform a motion cast to check if anything is collided with:

../../_images/spring_arm_camera_motion_cast.webp

Quando la forma colpisce un oggetto, la telecamera sarà posizionata esattamente o in prossimità del punto di collisione:

../../_images/spring_arm_camera_collision.webp

Configurare il braccio a molla e la telecamera

Aggiungiamo un sistema di telecamera con braccio a molla alla demo piattaforme.

Nota

È possibile scaricare la demo Platformer 3D da GitHub oppure attraverso la Libreria dei contenuti.

In generale, per un sistema di telecamera in terza persona, avrai tre nodi come figli del nodo che stai seguendo:

  • Node3D (il "punto perno" per la telecamera)

    • SpringArm3D

      • Camera3D

Apri la scena player/player.tscn. Imposta questi elementi come figli del nostro giocatore e assegna loro nomi univoci così da poterli trovare nel nostro script. Assicurati di eliminare il nodo telecamera esistente!

../../_images/spring_arm_editor_setup.webp

Spostiamo il punto perno di 2 verso l'alto sull'asse Y in modo che non si trovi a terra:

../../_images/spring_arm_pivot_setup.webp

Dai al braccio a molla una lunghezza di 3 in modo che sia posizionato dietro il personaggio:

../../_images/spring_arm_length_setup.webp

Nota

Lascia Shape del braccio a molla come <vuoto>. In questo modo, utilizzerà la forma piramidale della telecamera.

Se vuoi, puoi anche provare altre forme: una sfera è una scelta comune perché scorre agevolmente lungo i bordi.

Aggiorna la parte superiore di player/player.gd per recuperare la telecamera e i punti perno tramite i loro nomi univoci:

player/player.gd
# Comment out this existing camera line.
# @onready var _camera := $Target/Camera3D as Camera3D

@onready var _camera := %Camera3D as Camera3D
@onready var _camera_pivot := %CameraPivot as Node3D

Aggiungi una funzione _unhandled_input per verificare il movimento della telecamera e ruotare di conseguenza il punto perno:

player/player.gd
@export_range(0.0, 1.0) var mouse_sensitivity = 0.01
@export var tilt_limit = deg_to_rad(75)


func _unhandled_input(event: InputEvent) -> void:
    # Mouselook implemented using `screen_relative` for resolution-independent sensitivity.
    if event is InputEventMouseMotion:
        _camera_pivot.rotation.x -= event.screen_relative.y * mouse_sensitivity
        # Prevent the camera from rotating too far up or down.
        _camera_pivot.rotation.x = clampf(_camera_pivot.rotation.x, -tilt_limit, tilt_limit)
        _camera_pivot.rotation.y += -event.screen_relative.x * mouse_sensitivity

Ruotando il punto perno, anche il braccio a molla ruoterà, cambiando la posizione della telecamera. Avvia il gioco e noterai che ora il movimento del mouse fa ruotare la telecamera attorno al personaggio. Se la telecamera si muove contro un muro, lo urta.