Topic was automatically imported from the old Question2Answer platform.

Asked By

skippydog

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):

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:

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?

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

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