> For the complete documentation index, see [llms.txt](https://luisramirez.gitbook.io/godot-2.5d-rpg-course/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://luisramirez.gitbook.io/godot-2.5d-rpg-course/section-2-player-movement.md).

# Section 2: Player Movement

## Intro - Player Movement

This lecture does not contain notes.

## Adding Player Animations

In this lecture, we added animations to the player. During this process, we established a few rules regarding scenes.

1. Node names will be Pascal cased.
2. Scene files will remain snake-cased as recommended by Godot.
3. All scenes will be saved in a folder called **Scenes**.

Other than that, we also added animations. Refer to the video on how animations are set up for the player.

{% hint style="info" %}
Even though characters will be using 2D sprites, it's recommended to use 3D nodes for the sprites to be able to interact with 3D objects. **DO NOT** use the **CharacterBody2D** node. Otherwise, the game will not behave as expected.
{% endhint %}

## Attaching Scripts to Nodes

In this lecture, we learned how to attach a C# script to a node in Godot. There are a few conventions we'll be following in this course.

1. All C# scripts will be saved in a folder called **Scripts**.
2. C# files will be Pascal cased.
3. If a C# script is attached to a scene, the paths should reflect one another. For example, if a scene saved in the **Scenes/Characters/Player** has a script, the script should be saved in the **Scripts/Characters/Player** folder. Not required, but recommended.

We have two scenes. One is for the level called **Main**, and another is for the player called **Player**. The **Main** scene uses a **Node3D** node, and the **Player** scene should use the **CharacterBody3D** node since we'll be using physics to move the player around.&#x20;

## Configuring Visual Studio Code

In this lecture, we configured Visual Studio Code by installing an extension called. A link for this extension can be found here: <https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit>

In addition, we installed a theme called **Tokyo Night**, which can also be found here: <https://marketplace.visualstudio.com/items?itemName=enkia.tokyo-night>

Of course, you may prefer a different flavor of theme. Check out the resource section of this lecture for a site that can make it easier to browse various themes available for Visual Studio Code.

#### Resources

* VS Code Themes - <https://vscodethemes.com/>

## Overriding Methods

In this lecture, we learned about overriding methods. Godot's classes define methods that we can override, such as the `_PhysicsProcess` or `_Input` metho&#x64;**.** You can determine is overridable by checking where the method was originally defined and checking if it has the word **Virtual** next to it like in the screenshot below:

<figure><img src="/files/8XA9qYF0ZyN4qnaQXARd" alt=""><figcaption><p>Checking for the virtual keyword</p></figcaption></figure>

When using Godot's methods or properties, the documentation uses the GDScript naming convention. However, for C# users, names are converted into pascal case. So, `_physics_process` is actually written as `_PhysicsProcess` in C#. Keep that in mind as Godot doesn't provide many of its C# counterparts.&#x20;

Overriding a method can be done by adding the `override` keyword after the accessor like so:

```csharp
public override void _PhysicsProcess(double delta)
{
    GD.Print("Player physics process");
}
```

In addition to overriding methods, we learned about the `GD` class, which acts as a container for any other functions that don't belong to a node, such as the `Print()` method for printing text onto the output of the Godot editor.

#### Resources

* Godot Documentation - <https://docs.godotengine.org/en/stable/>

## Moving the Player

In this lecture, we learned how to move the player with the `CharacterBody3D` methods. Firstly, we had to set up the actions for our project. The following keys were bound in the input map:

* **MoveForward** = W
* **MoveLeft** = A
* **MoveBackward** = S
* **MoveRight** = D

Next, we had to generate a vector for determining where the player should be moved. Luckily, Godot has a method called `Input.GetVector()` which uses our actions to determine the vector value.

```csharp
public override void _Input(InputEvent @event)
{
    direction = Input.GetVector(
        "MoveLeft",
        "MoveRight",
        "MoveForward",
        "MoveBackward"
    );
}
```

The `GetVector()` method accepts the action for moving the player left, right, forward and backward **in that order**. This method returns the value as a `Vector2` type, which we store in a class variable called `direction`.&#x20;

Something to keep in mind is that the `_Input()` method gets called when a key is pressed **AND** released. So, the vector will get reset to a vector zero when the player releases a key, which is what we want to stop the player from moving when the key is no longer being pressed.&#x20;

Once we have the direction to player, we updated the `_PhysicsProcess` method by changing the `Velocity` property defined on the `CharacterBody3D` node. During this process, we have to convert the `Vector2` type to `Vector3`. The `Vector2.X` is mapped to  `Vector3.X` and the `Vector2.Y` is mapped to `Vector3.Z`. As for `Vector3.Y`, that is set to 0, as that'll move the player up and down in the air.

```csharp
public override void _PhysicsProcess(double delta)
{
    Velocity = new(direction.X, 0, direction.Y);
    Velocity *= 5;

    MoveAndSlide();
}
```

Lastly, we multipled the velocity by 5 so that the player moves faster and then called the `MoveAndSlide()` method to tell the `CharacterBody3D` node to begin moving the player. Simply setting the velocity does not move the player.

{% hint style="info" %}
During this process, we do not need to normalize the `Vector2` from the `GetVector()` method since it's already normalized, and we don't have to apply delta to the velocity since the `MoveAndSlide()` method already does so for us, too.
{% endhint %}

## Exporting Fields with Attributes

In this lecture, we decided to export fields from the `Player` class so that we can reference child nodes in the `Player` scene. Fields can be exported by using the `Export` attribute. Attributes are a feature in C# to communicate mainly with external programs, such as Godot. In the case of the `Export` attribute, we are telling it which fields/properties can be edited directly from the godot editor.

```csharp
[Export] private AnimationPlayer animPlayerNode;
[Export] private Sprite3D spriteNode;
```

In the example above, we exported fields for storing the `AnimationPlayer` and `Sprite3D` nodes. The class for a node can be found by hovering your mouse over the Node like so:

<figure><img src="/files/MhI0UlwKLxSFntZFkKEV" alt=""><figcaption></figcaption></figure>

After adding those fields, we must build our scripts before they'll appear in the editor by pressing the **Build** button in the top right corner.

<figure><img src="/files/eKxezC8U0DW4XT8GWUFh" alt=""><figcaption><p>The Build Button</p></figcaption></figure>

## Playing Animations

In this lecture, we learned how to play animations with the `AnimationPlayer` class. We can use the `Play()` method and provide the name of the animation (case-sensitive). For example, to play the idle animation, we would use the following code:

```csharp
animPlayerNode.Play("Idle");
```

We're playing the idle animation when the player is ready from the `_Ready` method. However, we want to change the animation when the player moves or stops moving. We updated the `_Input` method by adding the following conditional statements:

```csharp
if (direction == Vector2.Zero)
{
    animPlayerNode.Play("Idle");
}
else
{
    animPlayerNode.Play("Move");
}
```

In this example, we're checking if the player is moving by checking the `direction` variable. If it's `Vector2.Zero`, this means there is no movement. In that instance, we play the idle animation. Otherwise, we play the move animation.

## Game Constants

In this lecture, we created a class for holding strings to reduce the likelihood of typos throughout our program. We outsourced the strings for our input actions and animations called `GameConstants` like so:

```csharp
public class GameConstants
{
    // Animations
    public const string ANIM_IDLE = "Idle";
    public const string ANIM_MOVE = "Move";

    // Input
    public const string INPUT_MOVE_LEFT = "MoveLeft";
    public const string INPUT_MOVE_RIGHT = "MoveRight";
    public const string INPUT_MOVE_FORWARD = "MoveForward";
    public const string INPUT_MOVE_BACKWARD = "MoveBackward";
}
```

Constants are a feature in C# for variables that once they've been initialized with a value, they can never be modified. One of the benefits of using a constant is that we don't have to have an instance of a class to use the value. So, we can update the **Player.cs** file to use our constants instead of plain strings like so:

```csharp
animPlayerNode.Play(GameConstants.ANIM_IDLE);
```

We also used these constants in the `GetVector` method.

```csharp
direction = Input.GetVector(
  GameConstants.INPUT_MOVE_LEFT,
  GameConstants.INPUT_MOVE_RIGHT,
  GameConstants.INPUT_MOVE_FORWARD,
  GameConstants.INPUT_MOVE_BACKWARD
);
```

## Flipping the Player

In this lecture, we learned how to flip the player through their sprite node. Sprites have a property called **Flip H** for flipping a sprite horizontally. We want to flip the sprite based on the direction the player is facing. We defined a method called `Flip` in the **Player.cs** to tackle this problem.

```csharp
private void Flip()
{
    bool isNotMovingHorizontally = Velocity.X == 0;

    if (isNotMovingHorizontally) { return; }

    bool isMovingLeft = Velocity.X < 0;

    spriteNode.FlipH = isMovingLeft;
}
```

We're doing three things in this snippet of code.&#x20;

1. We're checking if the player is moving horizontally to begin with. If they're not, we shouldn't bother flipping them.
2. If they are moving horizontally, we check if the `Velocity.X` property is negative or positive. Negative means they're moving left. Positive means they're moving right.
3. Based on that information, we set the `FlipH` property to the `isMovingLeft` variable.

After defining this method, we're calling this method from the `_PhysicsProcess` method after changing the velocity since we only want to flip the player after their velocity has changed.

## Optimizing the Sprites

In this lecture, we learned how to optimize the sprites in Godot. There are no notes for this lecture. It's meant to be watched via video.&#x20;

## Partial Classes

In this lecture, we learned why it's necessary to add the `partial` keyword to our classes. If we ever inherit from any of Godot's classes, such as the `CharacterBody3D` class, the derived class must be marked as partial. This is because Godot performs code analysis on our code and injects additional code. The `partial` keyword permits Godot to inject more code into our classes.

Partial classes are also helpful in splitting large classes into multiple classes. However, it's typically recommended to use inheritance or composition. In most cases, partial classes are mostly used with source generation.
