Coding_Guy
Coding_Guy

Reputation: 151

How to make godot 4 3rd person camera with spring arm?

I am trying to make a 3rd person camera with spring arm in godot4. But I am a beginner in godot3D so I have no idea and all the tutorials are outdated. This is what I'm trying to do:enter image description here

(don't mind goofy domo square, it's just a mesh scene name) I have a collision shape, spring arm, and a camera. And I don't know how to control the camera using code. Can anyone please help me or just paste their old third person camera 3D code here? But remember, I want a traditional third person camera. Like you can rotate it all around the player and stuff.

Upvotes: 2

Views: 4598

Answers (1)

Theraot
Theraot

Reputation: 40295

You want something like this:

CharacterBody3D
├ ... other stuff ...
└ HorizontalPivot
  └ VerticalPivot
    └ SpringArm3D
      └ Camera3D

Then, from code, you will rotate your HorizontalPivot and VerticalPivot (they are just Node3D) horizontally and vertically, respectively, based on user input (either based on mouse motion, or based on joypad axis).

You, of course, would configure the SpringArm3D to extend away from the CharacterBody3D, with a collision shape (e.g. a sphere shape), and the collision mask set appropriately to collide with the environment.

And have the Camera3D pointing to the CharacterBody3D.


If you need to offset the camera, I strongly recommend to add additional Node3D:

CharacterBody3D
├ ... other stuff ...
└ CameraRootOffset
  └ HorizontalPivot
    └ VerticalPivot
      └ SpringArm3D
        └ CameraLeafOffset
          └ Camera3D

But do not displace them. Rotate them. For example the CameraRootOffset can have a 15 degrees rotation, and the CameraLeafOffset has a -15 degrees rotation. As a result of the SpringArm3D this will result in the Camera3D going off to the side... Tweak this to get an over the shoulder view (perhaps try to place the character according to the rule of thirds).


How do the pivots rotate?

They take input in _process, with some configuration sensitivity (you can export that property so you can tweak it in the inspector):

var input := Input.get_axis(negative_action, positive_action) * sensitivity * delta

Then you update the current angle:

current_angle = wrapf(current_angle, -PI, PI) + input

Here I'm wrapping it to the range from -PI to PI so it is expressed as the shorter rotation.

Ah, but you might want to clamp it to a minimum and maximum angle for the vertical pivot (angle range which you will also want to tweak from the inspector):

current_angle = clampf(
    wrapf(current_angle, -PI, PI),
    deg_to_rad(min_angle),
    deg_to_rad(max_angle)
)

And finally set a new transform based on the angle:

transform.basis = Basis(
    Quaternion(axis_3D, current_angle)
)

Here axis_3d is the rotation axis (so Vector3.UP for the horizontal rotation, and Vector3.RIGHT for the vertical).

Upvotes: 6

Related Questions