KinematicBody Player 3D is constantly shaking with a strange move, how to solve?

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

Hello people; first of all, I would like to let you know that I have knowledge of Godot 2D, but in Godot 3D I am a complete beginner;

I was trying to make the script as simple as possible for an original FPS Doom Style and I am completely lost when it comes to putting Gravity.

I made a very simple script and whenever I add gravity (as you can see, with move_vector.y), the character when walking is shaking as if he is constantly struggling to stabilize his position.
At first, I thought it was a problem with my script and then I tried to apply the Godot FPS tutorial script to my character and the same thing happens - even worse.

I am thinking that it is a problem with my floor, my meshes are made with StaticBodies; I remember that the Kinematic Body x Static Body relationship in Godot 2D was a problem.

Anyway, how can I solve and make my character more stable?

Below, code:

extends KinematicBody
const MOVE_SPEED = 4
const MOUSE_SENS = 0.2
const GRAVITY = 0.98

func _ready():
	mouse_capture()
	add_group()
func add_group():
	get_node(".").add_to_group("player")
func _process(delta):
	quit_game()
func _physics_process(delta):
	move_keyboard(delta)

func _input(event):
	mouse_direction(event)

func move_keyboard(delta):

	var move_vector = Vector3()
	if Input.is_action_pressed("move_forward"):
		move_vector.z -= 1
	if Input.is_action_pressed("move_backward"):
		move_vector.z += 1
	if Input.is_action_pressed("move_left"):
		move_vector.x -= 1
	if Input.is_action_pressed("move_right"):
		move_vector.x += 1

	move_vector.y -= GRAVITY

	move_vector = move_vector.rotated(Vector3(0, 1, 0), rotation.y)
	move_and_collide(move_vector * MOVE_SPEED * delta)

func mouse_capture():
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func mouse_direction(event):
	if event is InputEventMouseMotion:
		rotation_degrees.y -= MOUSE_SENS * event.relative.x
		rotation_degrees.x -= MOUSE_SENS * event.relative.y

func quit_game():
	if Input.is_action_pressed("quit"):
		get_tree().quit()

Attached, photos of my project and video

player scene pic

floor mesh scene

Youtube video of behaviour (the record is a lil bit slow than reality, but i think you can see):

PS: another thing I noticed: if I change the move_and_collide to move_and_slide and having a command from is_on_floor (), the player is never recognized as if it is is_on_floor ()

lucasfazzi | 2020-02-02 01:36

ps2: I printed player’s translation and he’s constantly changing Y:

(0.04475, 2.022034, 18.58946)
(0.085611, 1.9567, 18.642138)
(0.12487, 2.03533, 18.692751)
(0.16573, 1.969996, 18.733128)
(0.197819, 1.965178, 18.733038)
(0.229692, 1.98138, 18.73267)
(0.262206, 1.941978, 18.733128)
(0.291715, 2.04739, 18.731291)
(0.325299, 1.993691, 18.733128)
(0.357458, 1.942271, 18.733128)
(0.386958, 2.051677, 18.731043)
(0.420734, 1.99767, 18.733128)
(0.452893, 1.946249, 18.733128)
(0.492365, 2.041428, 18.742556)
(0.523576, 1.991523, 18.733128)
(0.555735, 1.940102, 18.733128)
(0.585496, 2.015728, 18.733128)
(0.617655, 1.964307, 18.733128)
(0.649815, 1.974988, 18.733128)
(0.681974, 1.953627, 18.733128)
(0.714133, 1.996348, 18.733128)
(0.746292, 1.944927, 18.733128)
(0.778451, 2.013747, 18.733128)
(0.778451, 1.948413, 18.733128)
(0.778451, 2.015728, 18.733128)
(0.778451, 1.950394, 18.733128)
(0.778451, 2.015728, 18.733128)
(0.778451, 1.950394, 18.733128)
(0.778451, 2.015728, 18.733128)
(0.778451, 1.950394, 18.733128)
(0.742254, 2.015728, 18.68646)
(0.701393, 1.950394, 18.633783)
(0.663504, 2.053318, 18.584936)
(0.622643, 1.987984, 18.532259)
(0.581783, 1.955458, 18.479582)
(0.541385, 2.038686, 18.4275)
(0.500524, 1.973352, 18.374823)
(0.459664, 1.983337, 18.319899)
(0.418803, 1.958392, 18.266365)
(0.377824, 2.005774, 18.210838)

lucasfazzi | 2020-02-02 01:54

:bust_in_silhouette: Reply From: aron137

Does it glitch if you remove this line temporarily?

rotation_degrees.x -= MOUSE_SENS * event.relative.y

I had a similar issue in Unity when I was changing the pitch of the collision body.

Resolution was changing only the yaw on the collision body, and pitch on the camera.

Godot’s FPS tutorial also uses a separate rotation_helper:

rotation_helper.rotate_x(deg2rad(event.relative.y * MOUSE_SENS * -1))
self.rotate_y(deg2rad(event.relative.x * MOUSE_SENS * -1))

You said you tried this script, but the results were even worse. Can you please describe what even worse means?

It was a problem with move_and_collide and the way I passed Gravity info;

Solved with this way:

	extends KinematicBody
const MOVE_SPEED = 4
const MOUSE_SENS = 0.2
const GRAVITY = 9.8


func _ready():
	mouse_capture()
	add_group()
func add_group():
	get_node(".").add_to_group("player")
func _process(delta):
	quit_game()
func _physics_process(delta):
	move_keyboard(delta)

func _input(event):
	mouse_direction(event)

func move_keyboard(delta):
	var velocity = Vector3()

	if Input.is_action_pressed("move_forward"):
		velocity.z -= 1
	if Input.is_action_pressed("move_backward"):
		velocity.z += 1
	if Input.is_action_pressed("move_left"):
		velocity.x -= 1
	if Input.is_action_pressed("move_right"):
		velocity.x += 1

	velocity.y -= (GRAVITY * 1)

	velocity = velocity.rotated(Vector3(0, 1, 0), rotation.y)
	move_and_slide(Vector3(velocity * MOVE_SPEED), Vector3(0,1,0), false, 4, 0.785398, false).normalized()


func mouse_capture():
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func mouse_direction(event):
	if event is InputEventMouseMotion:
		rotation_degrees.y -= MOUSE_SENS * event.relative.x
		rotation_degrees.x -= MOUSE_SENS * event.relative.y

func quit_game():
	if Input.is_action_pressed("quit"):
		get_tree().quit()

lucasfazzi | 2020-02-02 17:34