```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

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
``````

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,209 points)
+1 vote
by (1,045 points)