I've gotten `look_at()` working with the mouse successfully, so that the node rotates towards the mouse cursor, using this (basically from the Godot tutorials):

`look_at(get_local_mouse_position())`

Also I see how you can set rotation directly:

`rotation = position.angle_to_point(toplvl_canvas.get_local_mouse_position())`

What I can't for the life of me figure out is how to have different rotation rates than just the immediate snap to angle that look_at gives you. What I have so far is something like this:

``````var rot_speed = 0.02

steering_angle = position.angle_to_point(get_local_mouse_position()) - PI/2
if steering_angle - rotation < 0.1:
rotation -= rot_speed
elif steering_angle - rotation > 0.1:
rotation += rot_speed
``````

Which doesn't work when you cross from a small positive angle to -2PI, the zero crossing. It will find the difference to suddenly be the total angle in the other direction of rotation and loop around. I feel like this is something that many people must have implemented, but I haven't been able to figure it out. Is there something obvious I'm missing?

in Engine

+1 vote

When this happens to me I make myself a little function that adjusts one of the values so that the angle never crosses the 0 — 2PI boundary, and then uses the built-in `lerp()` function. Other engines, like unity have a `lerp_angle()` function built-in. Maybe it should be added to Godot too?

``````func lerp_angle(a, b, t): #In radians
if abs(a-b) >= PI:
if a > b:
b += 2 * PI
else:
a += 2 * PI
return lerp(a, b, t)
``````

EDIT: I didn't read the question that well. If you want to rotate at a set speed, use these:

``````func rotate_const_speed(a, b, d): #In radians
if abs(a-b) >= PI: #only need to adjust for the long way round
if a > b:
b += 2 * PI
else:
a += 2 * PI
return move_towards_float(a, b, d)

func move_towards_float (x, target, step): #Moves towards t without passing it
if abs(target - x) < abs(step):
return target
else: return x + step
``````
by (109 points)
selected

Thanks so much! I couldn't make this work in my head, and this was exactly what I was trying to build. I made one slight modification (probably obvious) to handle step direction, as I believe you would have to make that determination after adding 2PI.

``````func rotate_const_speed(a, b, d): #In radians
if abs(a-b) >= PI: #only need to adjust for the long way round
if a > b:
b += 2 * PI
else:
a += 2 * PI
if a > b:
d = -d
return move_towards_float(a, b, d)

func move_towards_float (x, target, step): #Moves towards t without passing it
if abs(target - x) < abs(step):
return target
else: return x + step
``````