Need help understanding Velocity and Vector2 to make player move

extends CharacterBody2D
@onready var anim_skel: AnimatedSprite2D = $AnimatedSprite2D
@export var char_move = 250

func _physics_process(_delta: float) → void:

var input_direction_x = Vector2.ZERO

if Input.is_action_pressed(“move_left”):
velocity.x = char_move * input_direction_x
anim_skel.play(“skeleton_walk”)
anim_skel.flip_h = true
print(input_direction_x)

if Input.is_action_pressed(“move_right”):
anim_skel.play(“skeleton_walk”)
anim_skel.flip_h = false

if Input.is_action_pressed(“attack”):
anim_skel.play(“skeleton_attack”)
else:
anim_skel.play(“skeleton_idle”)

move_and_slide()

I need help understanding how to move my character. Been stuck trying to make sense of how to use vector and velocity correctly to move left right up and down. Can someone help with what I’m doing wrong on my code that’s not making the player move? Ive tried different variations but I either get an error or something completely off

I will first clean up your code to use indentation otherwise you indeed get errors.
See below:

    extends CharacterBody2D

    @export var char_move = 250

    @onready var anim_skel: AnimatedSprite2D = $AnimatedSprite2D

    func _physics_process(_delta: float) → void:
      var input_direction_x = Vector2.ZERO
  
          if Input.is_action_pressed(“move_left”):
              velocity.x = char_move * input_direction_x
              anim_skel.play(“skeleton_walk”)
              anim_skel.flip_h = true
              print(input_direction_x)
  
          if Input.is_action_pressed(“move_right”):
               anim_skel.play(“skeleton_walk”)
               anim_skel.flip_h = false
  
          if Input.is_action_pressed(“attack”):
               anim_skel.play(“skeleton_attack”)
           else:
               anim_skel.play(“skeleton_idle”)
  
      move_and_slide()

Now lets look at the code line by line to understand the velocity and vectors like you wanted.

Vector introduction

First you need to know what a vector is. A Vector2 is a point in 2d space meaning it has an x and y component (variable).
Furthermore a vector can also be seen as the distance from the origin (0, 0).
This leads to the next thing, which is the length of the vector also called the magnitude sometimes. The length is the square root of (x^2 + y^2), this gives the distance to or from the origin. Think of the Pythagorean theorem.

Velocity

What does this have to do with velocity? Well, velocity is also a Vector2, giving yet another meaning to Vector2. For the velocity the x and y hold information on how far the CharacterBody2D moves each frame. So what you need to do is translate the amount of pixels to move either left or right (speed) to the velocity of the characterbody.

Code

Now take a look at the code starting from: var input_direction_x = Vector2.ZERO Here you create a variable called input_direction_x and set it equal to (x=0,y=0).

In the next line you check for input left, I assume you have this correctly setup.
For the next line: velocity.x = char_move * input_direction_x This is a bit weird to me as you set the x component of the velocity to 250 * (0,0). This should not be valid code but gdscript might fix this for you by just taking the x component of the input_direction_x variable.
What you would want to do here instead is the following: velocity.x = char_move * input_direction_x.x
I added the .x after the input_direction_x variable to get the x component. But this is zero so the velocity.x will be 0 after this. So before you do this but after the if statement you need to add the following input_direction_x.x = -1
Then in the right movement if statement set the variable to 1 instead and then set the x velocity to that multiplied by the char_move variable.

Now a double check is this how you should program it, not really.
You made input_direction_x a Vector2 but really it is just a float (you could even say an int but ignore that for now).

I will now give the completed code with the improvements I mentioned and how I would program it:

extends CharacterBody2D

@export var move_speed: float = 250

@onready var anim_skel: AnimatedSprite2D = $AnimatedSprite2D
var input_direction: float = 0.0

func _physics_process(_delta: float) → void:  
    input_direction = 0.0
    if Input.is_action_pressed(“move_left”):
        input_direction = -1.0
        anim_skel.play(“skeleton_walk”)
        anim_skel.flip_h = true
        print(input_direction_x)
  
    if Input.is_action_pressed(“move_right”):
        input_direction  = 1.0
        anim_skel.play(“skeleton_walk”)
        anim_skel.flip_h = false
  
    if Input.is_action_pressed(“attack”):
        anim_skel.play(“skeleton_attack”)
    else:
        anim_skel.play(“skeleton_idle”)
      
    velocity.x = move_speed * input_direction_x
    move_and_slide()

Let me go over the changes I made:
I changed the name from char_move to move_speed, purely for better readability.
I made the input_direction a global variable instead of being only in the _physics_process method, incase you need to use this elsewhere in your code.
I set it to 0 in the begin of the _physics_process method to reset the variable and now if you let go of the left or right keys you stop moving, if you remove that line see what happens instead if you let go of the keys.
Then in the if statements for movement I change the input_direction only and just before move_and_slide() I update the velocity.x with the new global variable

I hope this helps a bit good luck.
TLDR: copy the last code block if you just want it to work

1 Like

I really appreciate you taking the time to walk me through this it was very helpful! I took all the notes I could from this :smiley:

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