How can I have multiple velocities

Godot Version

4.2.2

Question

I am trying to get the player to always look at the mouse and thrust towards it and be able to strafe, i cant get it to do both at once, just backwards and forwards or side to side, I think the issue is that velocity it being over written, but I am stumped as to how to fix that

image

You are correct - your velocity is indeed being overwritten. Let’s try and describe exactly why this is happening, and what you can do to fix it.

Code analysis

To make sure that our understanding of your code is the same, I’m going to provide a line-by-line explanation of the code in your _physics_process() function.

    look_at(get_global_mouse_position())

Here you are making your CharacterBody2D look at the mouse’s global position. Nothing wrong here.

    var MoveInput = Input.get_axis("Back", "Forward")
    velocity = transform.x * MoveInput * Speed

These two lines will produce a velocity that is aligned with a single local axis – the x-axis. MoveInput is defined and used to store a float ranging from [-1, 1]. This float is then used to scale the x-axis vector retrieved from transform.x in order to control its direction and magnitude. Speed is used to achieve the desired speed by scaling the magnitude.

    var StrafeInput = Input.get_axis("Left", "Right")
    velocity = transform.y * StrafeInput * Speed

These two lines achieve the same as the previous two: an axis-aligned velocity. The only difference is the axis which is now the y-axis. Because velocity is assigned to again, the previous value is overwritten (your suspicion).

    move_and_slide()

The CharacterBody2D’s position is integrated based on velocity – the body moves.

The solution

Your problem is easily solved and there’s a variety of ways to do it. Below you can find one of the possible solutions followed by an explanation of the solution and other notes.

func _physics_process(delta):
    look_at(get_global_mouse_position())

    var MoveInput = Input.get_vector("Left", "Right", "Back", "Forward").normalized()
    var direction = transform.x * MoveInput.x + transform.y * MoveInput.y
    velocity = direction * Speed

    move_and_slide()

As is apparent by the use of a velocity, vectors is an important concept to get familiar with for movement systems. Vectors are important because they contain two vital pieces of information: direction and magnitude. In other words, they can elegantly describe the speed and direction of an object.

Notice, though, that was is being done in the solution is basically the same as what you did. The only real difference is that vectors are used to arrive at a single value which is then assigned to your velocity.

As you can see in the code above, Input.get_vector() is used to build an input-vector; a 2D vector that contains both of your input axes. The reason for building an input-vector is to avoid diagonal input (x- and y-input) that produces faster motion.

Example:
Input 1: [0, 1]
Input 2: [1, 1]

Input 2 has a larger magnitude.

However, once this is fixed – through a vector normalization – the separate axes of the input-vector can be utilized to compute a desired velocity vector (as seen in the code above).

Normalization example:
(Default vector) Input 3: [-1, 1] – length: 1,4142
(…Normalized…) Input 3: [-0.777, 0.777] – length: 1.0


EDIT: I realize now that I may not have been concise enough. If any of this causes confusion, please let me know.
1 Like

Thank you so much for an in depth reply to my problem

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.