Third person controller/ camera help

Godot Version

4.2.1

Question

I am working on a third person controller, I have made the camera rotate freely and follow the player, i am trying to add different functionality when the right mouse button is held down where by the camera is locked forward and the player rotates with the camera to assist with aiming the player will always point the way they are aiming.

See my code below, when I right click the player mesh rotates and faces the camera no matter where it is facing beforehand but i can’t see anything in the code that would be causing this behaviour. If anyone could help i would greatly appreciate. also any feedback on what i have so far would also be great as i am new to third person perspective and am having quite a hard time.

player.gd


const SPEED = 4.0
const JUMP_VELOCITY = 3.0
@onready var animation_player = $PlayerMesh/AnimationPlayer
@onready var player_mesh = $PlayerMesh
@onready var collision_shape_3d = $CollisionShape3D
@onready var spring_arm_3d = $SpringArm3D
@onready var camera_3d = $SpringArm3D/Camera3D
@onready var default_camera_position = $DefaultCameraPosition
@onready var aiming_camera_position = $AimingCameraPosition


var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
var aiming = false


func _ready():
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
	
	
func _input(event):
	if Input.is_action_pressed("aim"):
		aiming = true
	if Input.is_action_just_released("aim"):
		aiming = false


func _physics_process(delta):
	# Add the gravity.
	if not is_on_floor():
		velocity.y -= gravity * delta
	
	if aiming:
		#spring_arm_3d.global_position = lerp(spring_arm_3d.global_position, aiming_camera_position.global_position, 0.2)
		player_mesh.rotation.y = spring_arm_3d.rotation.y

	spring_arm_3d.global_position = lerp(spring_arm_3d.global_position, default_camera_position.global_position, 0.3)

	# Handle jump.
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = JUMP_VELOCITY

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var input_dir = Input.get_vector("left", "right", "forward", "backward")
	var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
	
	if direction:
		velocity.x = direction.normalized().x * SPEED
		velocity.z = direction.normalized().z * SPEED
		velocity = velocity.rotated(Vector3.UP, spring_arm_3d.rotation.y)
		
		if !aiming:
			player_mesh.rotation.y = lerp_angle(player_mesh.rotation.y, Vector2(velocity.z, velocity.x).angle(), 0.3)
			if animation_player.current_animation != "Walking0":
				animation_player.play("Walking0")
			
	else:
		if animation_player.current_animation != "NeutralIdle0":
			animation_player.play("NeutralIdle0")
			
		velocity.x = move_toward(velocity.x, 0, SPEED)
		velocity.z = move_toward(velocity.z, 0, SPEED)
		
	move_and_slide()

player_camera.gd

extends SpringArm3D

@export var mouse_sensitivity : float = 0.05
@onready var camera_reset_timer = $CameraResetTimer
@onready var player = $".."


func _ready():
	set_as_top_level(true)
	
	
func _unhandled_input(event):
	if event is InputEventMouseMotion:
		rotation_degrees.x -= event.relative.y * mouse_sensitivity
		rotation_degrees.x = clamp(rotation_degrees.x, -90.0, 30.0)
	
		rotation_degrees.y -= event.relative.x * mouse_sensitivity
		rotation_degrees.y = wrapf(rotation_degrees.y, 0.0, 360.0)
		
		camera_reset_timer.start()
			
		

worked it out, i replaced this

if aiming:
		#spring_arm_3d.global_position = lerp(spring_arm_3d.global_position, aiming_camera_position.global_position, 0.2)
		player_mesh.rotation.y = spring_arm_3d.rotation.y

with this

if aiming:
		player_mesh.rotation_degrees.y = spring_arm_3d.rotation_degrees.y + 180

any suggestions are still more than welcome :slight_smile:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.