Issues with rotation and lerp

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

Hello,

Here is a snippet of my code :

func _input(event):
    if event.is_action_released("turn right"):
       horizontal_rotation += 10
    if event.is_action_released("turn left"):
       horizontal_rotation -= 10

When I set “horizontal_rotation” to “target.rotation_degrees.y” like this:

target.rotation_degrees.y = horizontal_rotation #target is a KinematicBody

Everything works fine but, if I add a lerp in the mix like this :

target.rotation_degrees.y = lerp(target.rotation_degrees.y, horizontal_rotation, horizontal_acceleration * delta)

The rotation start to act weird when it reachs 180°… Here is the print of “target.rotation_degrees.y”:

179.941864
179.949631
181.289673
-129.548935
-86.942406
-50.01675
-18.014515
9.720756
33.757988
54.590256
72.644897
88.292244

At the first, I tought that the rotation was clamped between -180° and 180° but if I do something like :

target.rotation_degrees.y = 190

Everything works fine, I don’t know what I am missing.
Can someone explain to me this mystery, please ?

:bust_in_silhouette: Reply From: Firty

I will try to help you.
lerp_angle calculates the smallest distance between the current direction and the objective.
I use this on my NPCs when they need to spin smoothly until they are in the right direction.

var t0 = (dest-position).normalized()
rotation = lerp_angle(rotation,t0.angle(),0.1)
if self.get_angle_to(dest) < 0.1 and self.get_angle_to(dest) > -0.1:
This function will stop the rotation.

you just need to define the destination. Something like:
if input is right: dest = position+Vector2(0,10)
elif input is left: dest = position-Vector2(0,10)

This is summarized but I believe you understand kkkk
In short, it would be something like this:

var Status:int = 0
var dest:Vector2 = Vector2(0,0)

func _input(event):
	if event.is_action_pressed("ui_right"):
		dest = position+Vector2(0,10)
		Status = 1
	elif event.is_action_pressed("ui_left"):
		dest = position-Vector2(0,10)
		Status = 1
	elif event.is_action_pressed("ui_up"):
		dest = position-Vector2(10,0)
		Status = 1
	elif event.is_action_pressed("ui_down"):
		dest = position+Vector2(10,0)
		Status = 1

func _physics_process(_delta):
	if Status == 1:
		var t0 = (dest-position).normalized()
		rotation = lerp_angle(rotation,t0.angle(),0.1)
		if self.get_angle_to(dest) < 0.1 and self.get_angle_to(dest) > -0.1:
			Status = 0

Thank you for your answer, it works perfectly now !
Thanks a lot !

Roshi | 2021-04-05 19:01