This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
+1 vote

Hi there,
I'm trying to make a player rotate to face in the direction of a virtual joystick. I don't want to use look at(), because I want to be able to adjust the turning speed of the player, not have it instantly look in the direction of the joystick (unless this is possible with look at()).

Because I'm checking if rotation is larger or smaller than target dir, whenever target dir wraps around (goes from PI to -PI or the other way around), the player starts turning in the wrong direction.
Is there some obvious way around this, or built-in function I'm not seeing?
I appreciate any insight into this.

Here is the relevant code:

Joystick movement

#....
    var target_dir
    if !is_reversing:
        target_dir = Joystick.output.angle()
    else:
        target_dir = atan2(-Joystick.output.y, -Joystick.output.x) #opposite direction of Joystick in radians

    #a temporary, imperfect workaround. This makes it jumpy, and also does not work if the angle changes too suddenly.
    if rotation > 2.7 && target_dir < -2.7 :
        rotation = -PI
    if rotation < -2.7 && target_dir > 2.7 :
        rotation = PI

        #Set rotation direction
    rot_dir = 0
    if rotation > target_dir:
        rot_dir -= 1
    else:
        rot_dir += 1

#finally, apply rotation based on direction set.
rotation += rotation_speed * rot_dir * delta
in Engine by (31 points)

1 Answer

0 votes
Best answer

Update:

Solved my problem thanks to Dlean Jeans' answer here:
https://godotengine.org/qa/48342/lerp-rotation-with-above-180-degrees-difference?show=48342#q48342

Replaced

 #Set rotation direction
rot_dir = 0
if rotation > target_dir:
    rot_dir -= 1
else:
    rot_dir += 1

With

rot_dir = round(_short_angle_dist(rotation, target_dir))

Adding this function to the bottom of my script:

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

Using round() will make rotdir round to 2 or -2 if the angle is extreme, but I have decided to leave that in for now, as it just makes my movement feel a little snappier. You could always check if rotdir > 1 or < -1.

by (31 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 Frequently asked questions and 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 [email protected] with your username.