Hello,
I'm using this code:
to create a smooth turn whenever I move, but for some reason it keeps defaulting back to due north when I stop pressing any keys. If possible, I would like it to face the direction it stopped at.
Lerp_angle help
Here's all of it, if you need it.
It would be better if you posted the code text on the forum, not screenshots. Screenshots are hard to read, and can't be searched, or copied pasted. You can post code by typing 3 tildes ~~~ on a line by themselves directly above and directly below the code text.
To answer you question, you are setting direction equal to zero on the first line of process, so if no keys are pressed, you will have (0, 0, 0) for the rotation. You likely want to move the "var direction ..." line to the top under velocity and then change the inputs to use absolute instead of relative when adding 1. I would edit the code for you, but I can't, since you posted images rather than text.
cybereality Sorry about the screenshots, and thanks for the help. I’ll try it. The weird part is the character doesn’t start facing (0, 0, 0), it starts facing (0, 180, 0). Or maybe I’m mistaken, I’ll still try it and let you know.
cybereality I moved the var line, and for some reason it caused the character to fly around the screen. I'm also not sure what you mean by absolutes. Here's the code, sorry about the screenshots
extends KinematicBody
var velocity = Vector3.ZERO
export (int) var fall_acceleration = 75
export (int) var speed = 5
export(int) var rotSpeed = 1
export (int) var angluar_acceleration = 10
func _physics_process(delta):
var direction = Vector3.ZERO
if Input.is_action_pressed("MoveBackward"):
direction.z += 1
if Input.is_action_pressed("MoveForward"):
direction.z -= 1
if Input.is_action_pressed("MoveLeft"):
direction.x -= 1
if Input.is_action_pressed("MoveRight"):
direction.x += 1
if Input.is_action_pressed("MoveBackward") || Input.is_action_pressed("MoveForward") || Input.is_action_pressed("MoveLeft") || Input.is_action_pressed("MoveRight"):
velocity = Vector3(Input.get_action_strength("MoveLeft") - Input.get_action_strength("MoveRight"),
0,
Input.get_action_strength("MoveForward") - Input.get_action_strength("MoveBackward")).normalized()
else:
rotSpeed = 0
$model.rotation.y = lerp_angle($model.rotation.y, atan2(-velocity.x, -velocity.z), delta * angluar_acceleration)
#self.move_and_slide(velocity * speed, Vector3.UP)
velocity.x = direction.x * speed
velocity.z = direction.z * speed
velocity.y -= fall_acceleration * delta
velocity = move_and_slide(velocity * speed, Vector3.UP)
- Edited
I meant like this:
var velocity = Vector3.ZERO
var direction = Vector3.ZERO
export (int) var fall_acceleration = 75
export (int) var speed = 5
export(int) var rotSpeed = 1
export (int) var angluar_acceleration = 10
func _physics_process(delta):
if Input.is_action_pressed("MoveBackward"):
direction.z = 1
if Input.is_action_pressed("MoveForward"):
direction.z -= 1
if Input.is_action_pressed("MoveLeft"):
direction.x = -1
if Input.is_action_pressed("MoveRight"):
direction.x += 1
if Input.is_action_pressed("MoveBackward") || Input.is_action_pressed("MoveForward") || Input.is_action_pressed("MoveLeft") || Input.is_action_pressed("MoveRight"):
velocity = Vector3(Input.get_action_strength("MoveLeft") - Input.get_action_strength("MoveRight"),
0,
Input.get_action_strength("MoveForward") - Input.get_action_strength("MoveBackward")).normalized()
else:
rotSpeed = 0
$model.rotation.y = lerp_angle($model.rotation.y, atan2(-velocity.x, -velocity.z), delta * angluar_acceleration)
#self.move_and_slide(velocity * speed, Vector3.UP)
velocity.x = direction.x * speed
velocity.z = direction.z * speed
velocity.y -= fall_acceleration * delta
velocity = move_and_slide(velocity * speed, Vector3.UP)
cybereality That didn't work, all it did was make him go flying whenever I hit a key lol. The only change I see is the movement of the var, where is the absolutes change?
- Edited
Sorry, try this:
var velocity = Vector3.ZERO
var last_velocity = Vector3.ZERO
var direction = Vector3.ZERO
export (int) var fall_acceleration = 75
export (int) var speed = 5
export(int) var rotSpeed = 1
export (int) var angluar_acceleration = 10
func _physics_process(delta):
direction = Vector3.ZERO
if Input.is_action_pressed("MoveBackward"):
direction.z = 1
if Input.is_action_pressed("MoveForward"):
direction.z -= 1
if Input.is_action_pressed("MoveLeft"):
direction.x = -1
if Input.is_action_pressed("MoveRight"):
direction.x += 1
if Input.is_action_pressed("MoveBackward") || Input.is_action_pressed("MoveForward") || Input.is_action_pressed("MoveLeft") || Input.is_action_pressed("MoveRight"):
velocity = Vector3(Input.get_action_strength("MoveLeft") - Input.get_action_strength("MoveRight"),
0,
Input.get_action_strength("MoveForward") - Input.get_action_strength("MoveBackward")).normalized()
else:
rotSpeed = 0
if velocity.length_squared() > 0.1:
last_velocity = velocity
$model.rotation.y = lerp_angle($model.rotation.y, atan2(-last_velocity.x, -last_velocity.z), delta * angluar_acceleration)
velocity.x = direction.x * speed
velocity.z = direction.z * speed
velocity.y -= fall_acceleration * delta
velocity = move_and_slide(velocity * speed, Vector3.UP)
cybereality I tried it, and it works almost perfectly, but when the character stops they don't stop facing the direction they were last moving in. Instead, the turn 180 degrees and face the other way.
- Edited
Then it has something to do with these lines.
if velocity.length_squared() > 0.1:
last_velocity = velocity
$model.rotation.y = lerp_angle($model.rotation.y, atan2(-last_velocity.x, -last_velocity.z), delta * angluar_acceleration)
Honestly, that atan2 call doesn't make sense to me. Why are you using the negative value? Also, atan2 typically works with the reversed axis. In 2D it would be atan2(velocity.y, velocity.x)
. So the logic here seems incorrect.
cybereality I'm not sure, honestly I wasn't sure how to accomplish the task of turning the character such as I need since I've never worked with 3d before. I tried changing the negatives to positives, but no dice. If you have a suggestion that isn't atan2 I would love to hear it, but if not I could search for something else. You've already been a major help and I'd hate to bother you further.
- Best Answerset by PigeonTrash
I got it working. This is what I used:
extends KinematicBody
var velocity = Vector3.ZERO
var last_velocity = Vector3.ZERO
var direction = Vector3.ZERO
export (int) var fall_acceleration = 75
export (int) var speed = 5
export(int) var rotSpeed = 1
export (int) var angluar_acceleration = 10
var character_rot
func _physics_process(delta):
direction = Vector3.ZERO
character_rot = $model.get_rotation()
if Input.is_action_pressed("MoveBackward"):
direction.z = 1
if Input.is_action_pressed("MoveForward"):
direction.z -= 1
if Input.is_action_pressed("MoveLeft"):
direction.x = -1
if Input.is_action_pressed("MoveRight"):
direction.x += 1
if Input.is_action_pressed("MoveBackward") || Input.is_action_pressed("MoveForward") || Input.is_action_pressed("MoveLeft") || Input.is_action_pressed("MoveRight"):
velocity = Vector3(Input.get_action_strength("MoveLeft") - Input.get_action_strength("MoveRight"),
0,
Input.get_action_strength("MoveForward") - Input.get_action_strength("MoveBackward")).normalized()
else:
rotSpeed = 0
if velocity.length_squared() > 0.1:
var angle = atan2(-velocity.x, -velocity.z)
character_rot.y = lerp_angle(character_rot.y, angle, .1)
$model.set_rotation(character_rot)
velocity.x = direction.x * speed
velocity.z = direction.z * speed
velocity.y -= fall_acceleration * delta
velocity = move_and_slide(velocity * speed, Vector3.UP)