1

The current system applies a scale transformation to the CharacterBody2D when the current horizontal velocity is more or less than 0 based off of the current pressed input keys. This should work in theory, and by all means it should work. I have even tried isolating the movement of the character and the change in direction, with no avail.

When run, the D/right arrow key always faces the character to the right as it is supposed to. However, the A/left arrow causes it to constantly flip between facing left and facing right.

using Godot;

public partial class CharacterController : CharacterBody2D
{
    [Export]
    public int Speed { get; set; } = 100;
    private Vector2 velocity = new Vector2(0, 0);

    public void InputHandler()
    {
        Vector2 input_direction = Input.GetVector("move_left", "move_right", "move_up", "move_down");
        velocity = input_direction * Speed;
        GD.Print(input_direction);

        if (input_direction.X < 0) // Left
        {
            ApplyScale(new Vector2(-1, 1));
        }
        else if (input_direction.X > 0) // Right
        {
            ApplyScale(new Vector2(1, 1));
        }
    }

    public override void _PhysicsProcess(double delta)
    {
        InputHandler();
        var collision_info = MoveAndCollide(velocity * (float)delta);
        if (collision_info == null)
        {
            MoveAndSlide();
        }

    }
}
Sprunk
  • 13
  • 4

1 Answers1

1

Yes, of course your player sprite keeps flipping its orientation as long as move_left inputs are entered. Because you always apply a -1, 1 mirror scaling for every move_left input.

So, basically your code does this while you are trying to move the sprite to the left:

S * -1 => -S
-S * -1 => S
S * -1 => -S
-S * -1 => S
... etc... 

However, you need to apply the -1, 1 mirror scale transform only when the horizontal input direction changes, not for every move_left input.

Note that a horizontal input direction change happens when either the last horizontal move input was move_left and the next horizontal move input is move_right, or vice versa.

You can detect a horizontal move input by checking whether input_direction.X is non-zero. To detect a change in direction, you need to check whether the sign of the last non-zero(!) input_direction.X value is different from the sign of the next non-zero(!) input_direction.X value. And only when a change in direction is detected, apply the -1, 1 mirror scale transform.

(As a side note: Your 1,1 scaling for the move_right input does nothing, as it leaves your sprite at the size and orientation it currently is, because multiplying a value with 1 will only ever result in the unchanged value itself, obviously. That means it would not flip a left-facing sprite to face to the right upon a move_right input, contrary to what you seem to believe.)