0 votes

I implemented a joystick for a mobile game project but it doesn't work when i normalize the vector and multiply it by the speed.
These are the player script and a piece of debug text i collected (i cut some lines for it to be more understandable).

Player script:

extends KinematicBody2D


var dir = Vector2();
var vel = Vector2();


func _physics_process(delta):
    process_movement(delta);

func process_movement(delta):
    var dir = $UI/Joystick/Joystick.movement;
    dir = -dir.normalized();

    vel = dir*250.0;

    print(vel)

    vel = move_and_slide(vel,Vector2(0.0,1.0));

Debug text:

(-0, -0)
(176.776688, -176.776688)
(176.776688, -176.776688)
(176.776688, -176.776688)
(176.776688, -176.776688)
(237.170822, -79.056938)
(248.470917, -27.60788)
(249.688095, -12.484405)
(249.935455, 5.680351)
(250, -0)
(250, -0)
(250, -0)
(250, -0)

As you can see, vel goes from 0 to (176,-176) to (248,-27) when i drag the button, which is intended. But when i release it, the value doesn't change, then becomes the factor i'm multiplying by (250) and drops to 0.
I've tried this without normalizing dir and it works. It seems like a problem with "normalized()", but i'm not sure.

in Engine by (19 points)

Print $UI/Joystick/Joystick.movement as well. If it's not exactly 0,0 it will still get normalized.

It's not clear what you're actually looking for here. It almost looks like you want a binary mechanism where when you're not touching the stick, you get no motion, and when you are touching the stick (even just a tiny bit), you get full speed motion. Is that correct?

I'd say the immediate problem is exactly as pointed out by @Masgo - your values aren't exactly 0,0 when you release, and that's getting normalized back into a full-length vector.

Maybe you can provide some more explanation of the intended result?

If you really are looking for a binary mechanism (as described above), something like this should probably fix your problem:

func process_movement(delta):
    var dir = $UI/Joystick/Joystick.movement;

    if is_equal_approx(0, dir.length):
        dir = Vector2.ZERO

    dir = -dir.normalized();

    vel = dir*250.0;

    print(vel)

    vel = move_and_slide(vel,Vector2(0.0,1.0));

So, just reset the vector if its length is very nearly zero. Depending on your needs, you could bypass some of the other code there as well if the vector length is nearly zero...

Please log in or register to answer this question.

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 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 webmaster@godotengine.org with your username.