Reputation: 151
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:
(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
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