0 votes

if is_moving: end_angle = input_movement_vector.angle() + deg2rad(90) $MeshInstance.rotation.y = lerp($MeshInstance.rotation.y, end_angle, 0.08)

The following code smoothly rotates a mesh from its current position to end_angle, which is dependant on input and only updates if buttons are being pressed, so that the mesh can finish its smooth rotation even when there is no input.

inputmovementvector updates as follows: "W" corresponds to positive Y (negative Z in 3D), and "D" to positive X. When any of the WASD buttons are pressed, this vector's components update accordingly and get normalized. If no buttons are being pressed, it's set to 0. It is completely independent from the Mesh's rotation.


Now here's the issue:
When I try to rotate from left to down (from A to S, or from A to A+S) and vice versa, instead of perfomring a smooth rotation in the correct direction, the mesh instead rotates in the opposite direction, preforming almost a full 360 degree rotation.

I have tried using linear_interpolate with rotation vector and inputmovementvector, didn't help. Tried writing special cases for specific button inputs or rotation angles, couldn't figure out how to rotate smoothly in the right direction. I would like to recieve help with the matter, or know the cause of the problem at least.

in Engine by (141 points)

3 Answers

0 votes

I solved the problem. I used the methods set_rotation() and atan2() instead of lerp. Here's the final code:

if is_moving:
    var angle = atan2(hvel.x, hvel.z)
    var rotation = self.get_rotation()
    rotation.y = angle
    self.set_rotation(rotation)

where hvel is horizontal velocity in 3d space

by (141 points)

That won't be lerping anymore, I guess.
Also:

var rotation = self.get_rotation()
rotation.y = angle
self.set_rotation(rotation)

can be shortened to just:

rotation.y = angle
+3 votes

Use this if you wanna lerp between angles:

static func lerp_angle(from, to, weight):
    return from + _short_angle_dist(from, to) * weight

static func _short_angle_dist(from, to):
    var max_angle = PI * 2
    var difference = fmod(to - from, max_angle)
    return fmod(2 * difference, max_angle) - difference
by (4,103 points)
+1 vote
by (1,044 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 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 webmaster@godotengine.org with your username.