# Moving the player with codeΒΆ

It's time to code! We're going to use the input actions we created in the last part to move the character.

Right-click the `Player` node and select Attach Script to add a new script to it. In the popup, set the Template to Empty before pressing the Create button.

Let's start with the class's properties. We're going to define a movement speed, a fall acceleration representing gravity, and a velocity we'll use to move the character.

```extends CharacterBody3D

# How fast the player moves in meters per second.
@export var speed = 14
# The downward acceleration while in the air, in meters per second squared.
@export var fall_acceleration = 75

var target_velocity = Vector3.ZERO
```

These are common properties for a moving body. The `velocity` is a 3D vector combining a speed with a direction. Here, we define it as a property because we want to update and reuse its value across frames.

Note

The values are quite different from 2D code because distances are in meters. While in 2D, a thousand units (pixels) may only correspond to half of your screen's width, in 3D, it's a kilometer.

Let's code the movement. We start by calculating the input direction vector using the global `Input` object, in `_physics_process()`.

```func _physics_process(delta):
# We create a local variable to store the input direction.
var direction = Vector3.ZERO

# We check for each move input and update the direction accordingly.
if Input.is_action_pressed("move_right"):
direction.x += 1
if Input.is_action_pressed("move_left"):
direction.x -= 1
if Input.is_action_pressed("move_back"):
# Notice how we are working with the vector's x and z axes.
# In 3D, the XZ plane is the ground plane.
direction.z += 1
if Input.is_action_pressed("move_forward"):
direction.z -= 1
```

Here, we're going to make all calculations using the `_physics_process()` virtual function. Like `_process()`, it allows you to update the node every frame, but it's designed specifically for physics-related code like moving a kinematic or rigid body.

To learn more about the difference between `_process()` and `_physics_process()`, see Idle and Physics Processing.

We start by initializing a `direction` variable to `Vector3.ZERO`. Then, we check if the player is pressing one or more of the `move_*` inputs and update the vector's `x` and `z` components accordingly. These correspond to the ground plane's axes.

These four conditions give us eight possibilities and eight possible directions.

In case the player presses, say, both W and D simultaneously, the vector will have a length of about `1.4`. But if they press a single key, it will have a length of `1`. We want the vector's length to be consistent, and not move faster diagonally. To do so, we can call its `normalize()` method.

```#func _physics_process(delta):
#...

if direction != Vector3.ZERO:
direction = direction.normalized()
\$Pivot.look_at(position + direction, Vector3.UP)
```

Here, we only normalize the vector if the direction has a length greater than zero, which means the player is pressing a direction key.

In this case, we also get the `Pivot` node and call its `look_at()` method. This method takes a position in space to look at in global coordinates and the up direction. In this case, we can use the `Vector3.UP` constant.

Note

A node's local coordinates, like `position`, are relative to their parent. Global coordinates, like `global_position` are relative to the world's main axes you can see in the viewport instead.

In 3D, the property that contains a node's position is `position`. By adding the `direction` to it, we get a position to look at that's one meter away from the `Player`.

Then, we update the velocity. We have to calculate the ground velocity and the fall speed separately. Be sure to go back one tab so the lines are inside the `_physics_process()` function but outside the condition we just wrote above.

```func _physics_process(delta):
#...
if direction != Vector3.ZERO:
#...

# Ground Velocity
target_velocity.x = direction.x * speed
target_velocity.z = direction.z * speed

# Vertical Velocity
if not is_on_floor(): # If in the air, fall towards the floor. Literally gravity
target_velocity.y = target_velocity.y - (fall_acceleration * delta)

# Moving the Character
velocity = target_velocity
move_and_slide()
```

The `CharacterBody3D.is_on_floor()` function returns `true` if the body collided with the floor in this frame. That's why we apply gravity to the `Player` only while he is in the air.

For the vertical velocity, we subtract the fall acceleration multiplied by the delta time every frame. This line of code will cause our character to fall in every frame, as long he is not on the floor, or collides with it.

The physics engine can only detect interactions with walls, the floor, or other bodies during a given frame if movement and collisions happen. We will use this property later to code the jump.

On the last line, we call