The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

0 votes

So, I'm making a game in 3D and whenever the player is in the air and I'm not holding one of the direction buttons, the player will always snap to face the same direction it was looking in when the scene loaded. What is causing this and how do I fix it?

Here is the script for controlling the player:

extends KinematicBody

export var speed = 10 
export var jump_strength = 20
export var gravity = 50 
export var controller_sensitivity = 5

var velocity = Vector3.ZERO 
var snap_vector = Vector3.ZERO

onready var spring_arm: SpringArm = $SpringArm 
onready var model: Spatial = $Skin

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

func _unhandled_input(event):   
 if event.is_action_pressed("click"):        
  Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)       
 if event.is_action_pressed("toggle_mouse_captured"):       
  if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:            
   Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)       
 else:          
   Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _physics_process(delta):   
 var move_direction = Vector3.ZERO  
 move_direction.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")    
 move_direction.z = Input.get_action_strength("move_back") - Input.get_action_strength("move_forward")  
 move_direction = move_direction.rotated(Vector3.UP, spring_arm.rotation.y).normalized()    

 velocity.x = move_direction.x * speed  
 velocity.z = move_direction.z * speed  
 velocity.y -= gravity * delta

 var just_landed = is_on_floor() and snap_vector == Vector3.ZERO
 var is_jumping = is_on_floor() and Input.is_action_just_pressed("jump")
 if is_jumping:
  velocity.y = jump_strength 
  snap_vector = Vector3.ZERO    
 elif just_landed:  
  snap_vector = Vector3.DOWN        

 velocity = move_and_slide_with_snap(velocity, snap_vector, Vector3.UP, true)       

 if velocity.length() > 0.2:        
  var look_direction = Vector2(velocity.z, velocity.x)      
  model.rotation.y = look_direction.angle()

func _process(delta):   
 spring_arm.translation = translation
Godot version 3.4.1
in Engine by (14 points)

Maybe this part is the problem? Have you tried moving it above the code for move_and_slide_with_snap()?

if velocity.length() > 0.2:        
  var look_direction = Vector2(velocity.z, velocity.x)      
  model.rotation.y = look_direction.angle()

Doing that makes it worse. It causes the snap issue to happen even when on the ground.

Then maybe it's with these lines? Maybe it would be better (or easier to read) by refactoring the code?

var just_landed = is_on_floor() and snap_vector == Vector3.ZERO
var is_jumping = is_on_floor() and Input.is_action_just_pressed("jump")

It's not with those lines either.

I've actually managed to fix the bug with the addition of a few lines of code, but I'd still like to know what caused it in the first place. I've tried removing and changing every bit of the code but I still can't figure out the cause.

1 Answer

0 votes

I set up my rotation exactly like this by following a GDQuest tutorial and had the exact same issue. It seems like something about our jumping process is fighting with our rotation statement. I'm guessing it's either our velocity.y variable being affected by the jump or it's our snap_vector being set to Vector3.ZERO. Not sure how or why those would affect it.

Anyways, replacing the if statement for the rotation with the below code seems to fix it:

if Vector2(velocity.z, velocity.x).length() > 0.2:
    var look_direction = Vector2(velocity.z, velocity.x)
     model.rotation.y = look_direction.angle()

Thanks to the Youtube commenters for figuring this one out. Still not sure why this works, or why it was a problem in the first place, but this solution seems to work out fine.

by (14 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.