This question is related to this discussion:
(https://godotforums.org/d/35504-script-of-camera-and-movements-limits/)

I am looking for help to understand and formulate a solution to this problem (any advice is welcome).
I want to get a "dynamic smooth camera" as a result:

  • The player must be able to rotate the camera only with the mouse...
  • ...and only with the controls move in the direction indicated by the camera.

Now the problems:
1. Visuals (Mesh of player) do not move in the direction indicated and keep facing the map axis.

extends CharacterBody3D

@onready var visuals := $visuals as Node3D
@onready var mount := $mount as Node3D
@onready var spring := $mount/spring as SpringArm3D

var mouse_sensitivity := 0.5

const ANGULAR_SPPED : float = TAU


func _ready() -> void:
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)


func _unhandled_input(event: InputEvent) -> void:
    if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
       mount.rotate_y(deg_to_rad( - event.relative.x * mouse_sensitivity))
       spring.rotate_x(deg_to_rad( - event.relative.y * mouse_sensitivity))
       spring.rotation.x = clampf(spring.rotation.x, -PI/4, PI/4)
       spring.rotation.z = clampf(spring.rotation.y, -PI/4, PI/4)


func _physics_process(delta: float) -> void:
	var input_dir := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	var direction := (mount.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
        
        if input_dir.length_squared() > 0:
            target_angle = 0.75 * TAU - input_dir.angle()
        var angle_diff := wrapf(target_angle - visuals.rotation.y, -PI, PI)
        
        if direction:
		visuals.rotation.y += clampf(delta * ANGULAR_SPPED, 0, absf(angle_diff)) * signf(angle_diff)
		velocity.x = direction.x * movement_speed
		velocity.z = direction.z * movement_speed
	else:	
		velocity.x = 0.0
		velocity.z = 0.0

I have change this line, by adding "mount" at beginning, to have the rotation relative at "player-neck":

var direction := (mount.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()

This is the solution of this problem:
Smooth target angle fixed to X and Y vectors (i guess).
Wrong line: target_angle = 0.75 * TAU - input_dir.angle() need to be change with:

target_angle = 0.75 * TAU - direction.signed_angle_to(Vector3(1,0,0), Vector3(0,1,0))

Well..solution founded (i hope) by replacing this target_angle = 0.75 * TAU - input_dir.angle() with:

target_angle = 0.75 * TAU - direction.signed_angle_to(Vector3(1,0,0), Vector3(0,1,0))

Was simple, just smash my head on every single godot command and combination 😃