look_at() screwing with player controller's movevement using move_and_slide()

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By spiderbyte87

The game is third person with a camera that follows the player. The player can rotates to follow the mouse motion. I’m using look_at() for rotation and move_and_slide() for movement. The problem is that when I rotate the player movement get slower the closer it gets to perpendicular to the forward rotation.

Here’s a video:

look_at() and move_and_slide() are both global space and I know I could rotate the player locally, but it makes firing projectiles much more complicated.

Here’s my controller:
(doing the look_at() in _process() isn’t necessary but it seems to run faster that way)

var from = Vector3()
var to = Vector3()
onready var camera = get_node("../Camera")
onready var jumpRay = get_node("JumpRay")
onready var base = get_node("..")
export var gravity = .1
export var jumpForce = 30
var velocity = Vector3(0,0,0)
export var SPEED = 30

func _physics_process(delta):
	if Input.is_action_pressed("STRAFE_RIGHT") and Input.is_action_pressed("STRAFE_LEFT"):
		velocity.x = 0
	elif Input.is_action_pressed("STRAFE_RIGHT"):
		velocity.x = 1
	elif Input.is_action_pressed("STRAFE_LEFT"):
		velocity.x = -1
	else:
		velocity.x = lerp(velocity.x,0,0.1)
	if Input.is_action_pressed("FORWARD") and Input.is_action_pressed("BACK"):
		velocity.z = 0
	elif Input.is_action_pressed("FORWARD"):
		velocity.z = -1
	elif Input.is_action_pressed("BACK"):
		velocity.z = 1
	else:
		velocity.z = lerp(velocity.z,0,0.1)

	if Input.is_action_just_pressed("JUMP") and jumpRay.is_colliding() == true:
		velocity.y = lerp(velocity.y, velocity.y * -jumpForce, .1)
	else: 
		velocity.y = velocity.y - gravity
		velocity.y = lerp(velocity.y,0,0.1)
	
	move_and_slide(velocity*SPEED)
	
func _process(delta):
	from = camera.project_ray_origin(get_viewport().get_mouse_position())
	to = from + camera.project_ray_normal(get_viewport().get_mouse_position()) * 1000
	
	var cameraOffset = get_translation() + Vector3(11,28,27)
	camera.look_at_from_position(cameraOffset,get_translation(),Vector3(0,1,0))
	
	var space_state = get_world().direct_space_state
	var ray = space_state.intersect_ray(from, to, [self,$guns,base],1, true, true)
	var rayPOS = ray.get("position",Vector3(0,1,0))
	$guns.look_at(Vector3(rayPOS.x,rayPOS.y,rayPOS.z), Vector3(0,1,0))
	rayPOS.y = get_global_transform().origin.y
	look_at(rayPOS,Vector3(0,1,0))
:bust_in_silhouette: Reply From: spiderbyte87

Okay I figured out what I was doing wrong.

I decoupled the rotation from the movement by nesting the player’s KinematicBody inside another KinematicBody. So the tree looks like this:

MAIN (move this)
|-BODY (rotate this)

It’s also VERY important that the collision bodies of these two are separated. I just put the BODY in a different layer and set the masks appropriately.

Very simple and pretty obvious now that I figured it out. All it took was a good nights sleep.