How to get my player model to rotate in the direction of player movement

Godot Version

4.5.1

Question

This is a relatively simple question, but I just cannot figure out how to rotate my player model correctly.

For context, I’m working on a third-person shooter with a focus on movement in 3D space.

When the player is not shooting, their model is intended to rotate towards their movement direction, not camera direction. Kind of like a 3D platformer player character.

Luckily, there are only a few relevant parts of code to go over.


Relevant variable(s):

var Global_Movement_Direction : Vector3 

How the movement code is triggered:

# Checks if the player is holding any movement button
	if Is_Holding_Move_Forward_Input == true \
	or Is_Holding_Move_Backward_Input == true \
	or Is_Holding_Move_Right_Input == true \
	or Is_Holding_Move_Left_Input == true:
		
		# Get player input vectors
		var input:Vector2 = Input.get_vector("move_right", "move_left", "move_backward", "move_forward")
		
		# Move the player on the client
		Client_Player.start_moving(input, delta)

The movement function itself:

func start_moving(input:Vector2, delta:float) -> void:
	
	# Set moving to true
	Is_Moving = true
	
	# Set the current movement direction
	Global_Movement_Direction = Camera_Horizonal_Rotation.basis \
	* Vector3(input.x, 0, input.y)
	
	# Walking movement acceleration (Advances every physics tick in the client script)
	if Current_Movement_Speed < MAX_MOVEMENT_SPEED * Current_Movement_Speed_Multiplier:
		
		Current_Movement_Speed = \
		clampf(Current_Movement_Speed + \
		(delta * MOVEMENT_ACCELERATION_RATE), \
		MIN_MOVEMENT_SPEED, MAX_MOVEMENT_SPEED * Current_Movement_Speed_Multiplier)
	
	# Movement force
	velocity.x = Global_Movement_Direction.x * Current_Movement_Speed
	velocity.z = Global_Movement_Direction.z * Current_Movement_Speed
	
	# THIS IS THE PART THAT DOESN'T WORK
	Body_Parts.rotation.y = Global_Movement_Direction.y

Here’s the scene tree for reference to where Body_Parts are:


I’m having trouble figuring out how to convert the Global_Movement_Direction into a rotation for the player’s Body_Parts.

Any help would be appreciated.

Use look_at()

2 Likes

Could you provide a code example? I just haven’t used look_at() in a while.

look_at(global_position + Global_Movement_Direction)
1 Like

If only y axis rotation is needed I think a better solution would be to use atan2 like so:

rotation.y = atan2(Global_Movement_Direction.x,Global_Movement_Direction.z)

1 Like

Euler angles are never a better solution for 3d orientation. It’ll start causing problems sooner or later. Best to get used to work with bases from a get go.

1 Like

Ok, I’ve never heard of atan2, but it actually worked!:

Body_Parts.rotation.y = atan2(Global_Movement_Direction.x, Global_Movement_Direction.z)
Head_Parts.rotation.y = atan2(Global_Movement_Direction.x, Global_Movement_Direction.z)

Now, I just need to add rotation behavior for when the player stops moving and add a little interpolation for the rotation.

Thanks for all the help.

You can further optimize it by calculating the angle once and then assigning it both transforms

var rotation_degrees = atan2(Global_Movement_Direction.x, Global_Movement_Direction.z)
Body_Parts.rotation.y = rotation_degrees
Head_Parts.rotation.y = rotation_degrees

And a little lerp would make it feel really smooth indeed :slight_smile:

2 Likes