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.

Cámara en tercera persona con brazo de resorte

Introducción

Los juegos 3D a menudo tendrán una cámara en tercera persona que sigue y rota al rededor de algo como un jugador o un vehículo.

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.

Aquí es donde entra el nodo SpringArm3D.

¿Qué es un brazo de resorte?

Un brazo de resorte tiene dos componentes principales que afectan a su comportamiento.

La «longitud» del brazo de resorte es cómo de lejos de su posición global debe revisar en busca de colisiones:

../../_images/spring_arm_position_length.webp

La «forma» del brazo de resorte es qué utiliza para buscar colisiones. El brazo de resorte barrerá esta forma desde su origen hacia su longitud.

../../_images/spring_arm_shape.webp

El brazo de resorte intenta mantener todos sus hijos al final de su longitud. Cuando la forma colisiona con algo, los hijos pasan a posicionarse en el punto de colisión o cerca del mismo:

../../_images/spring_arm_children.webp

Brazo de resorte con una cámara

Cuando la cámara se coloca como hija de un brazo de resorte, se usará una pirámide que representa a la cámara como su forma.

This pyramid represents the near plane of the camera:

../../_images/spring_arm_camera_shape.webp

Nota

Si se le da una forma específica al brazo de resorte, entonces siempre se usará dicha forma.

La forma de la cámara solo se usa si la cámara es hija directa del brazo de resorte.

Si no se proporciona ninguna forma y la cámara no es una hija directa, el brazo de resorte recurrirá a utilizar ray cast, lo que es impreciso para colisiones de cámara y no se recomienda.

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

When the shape hits something, the camera will be placed at or near the collision point:

../../_images/spring_arm_camera_collision.webp

Configurar el brazo de resorte y la cámara

Let's add a spring arm camera setup to the platformer demo.

Nota

You can download the Platformer 3D demo on GitHub or using the Asset Library.

In general, for a third-person camera setup, you will have three nodes as children of the node that you're following:

  • Node3D (the "pivot point" for the camera)

    • SpringArm3D

      • Camera3D

Open the player/player.tscn scene. Set these up as children of our player and give them unique names so we can find them in our script. Make sure to delete the existing camera node!

../../_images/spring_arm_editor_setup.webp

Let's move the pivot point up by 2 on the Y-axis so that it's not on the ground:

../../_images/spring_arm_pivot_setup.webp

Ponle una longitud de 3 al brazo de resorte para que se coloque detrás del carácter:

../../_images/spring_arm_length_setup.webp

Nota

Deja la Forma del brazo de resorte como <vacío>. Así, siempre se usará la forma de pirámide de la cámara.

If you want, you can also try other shapes - a sphere is a common choice since it slides smoothly along edges.

Update the top of player/player.gd to grab the camera and the pivot points by their unique names:

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

Add an _unhandled_input function to check for camera movement and then rotate the pivot point accordingly:

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

By rotating the pivot point, the spring arm will also be rotated and it will change where the camera is positioned. Run the game and notice that mouse movement now rotates the camera around the character. If the camera moves into a wall, it collides with it.