Input press is being ignored when diagonal movement is performed (2 arrow keys pressed)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By fiifciia

Hi, I am rather new to GDScript and Godot but I am having a strange issue with Godot 4.0.2.

I have implemented an 8-dimensional movement for a character. Normally when the player is moving and hits the melee button, movement is stopped and melee animation is performed. The same happens with ranged attack functionality BUT it doesn’t work just when the character is moving to the north/east direction (I am attaching a yt video as a visual explanation https://youtu.be/w9KKr_JxTyk )

Below I am adding my code. Both melee and ranged attacks are very very similar + this issue happens JUST when a player goes to the N-E direction.
Big thank you for any support

extends CharacterBody2D

const SPEED = 75
const UP = "back"
const DOWN = "front"
const RIGHT = "right"
const LEFT = "left"

@onready
var ANIMATION = $AnimationPlayer
@onready
var SKIN = $Body
@onready
var WEAPON = $Weapon
@onready
var SHIELD = $Shield
@onready
var BOW = $Bow
var direction_facing = DOWN
var duringAction = false
var vector = Vector2.ZERO

func _ready():
	BOW.visible = false

func _physics_process(delta):
	if !duringAction:
		player_input()

func player_input():
	if Input.is_action_just_pressed("e"):
		print("e")
		attack(true)
	elif Input.is_action_pressed("f"):
		print("f")
		attack(false)
	elif Input.is_action_pressed("ui_left"):
		print("l")
		walk(true, LEFT)
	elif Input.is_action_pressed("ui_right"):
		print("r")
		walk(true, RIGHT)
	elif Input.is_action_pressed("ui_up"):
		print("up")
		walk(true, UP)
	elif Input.is_action_pressed("ui_down"):
		print("down")
		walk(true, DOWN)
	elif Input.is_action_just_pressed("1"):
		change_skin(1)
	elif Input.is_action_just_pressed("2"):
		change_skin(2)
	elif Input.is_action_just_pressed("3"):
		change_weapon(1)
	elif Input.is_action_just_pressed("4"):
		change_weapon(2)
	else:
		play_walking_or_idle_animation(false)
		velocity.x = 0
		velocity.y = 0

func calculateWalkingVector():
	vector.x = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
	vector.y = Input.get_action_strength("ui_down") - Input.get_action_strength("ui_up")
	vector = vector.normalized()

func walk(playWalkingAnimation, directionFacing):
	calculateWalkingVector()
	direction_facing = directionFacing
	velocity = vector * SPEED
	play_walking_or_idle_animation(playWalkingAnimation)

func attack(ranged):
	duringAction = true
	if ranged:
		play_ranged_animation()
		await get_tree().create_timer(.45).timeout
	elif (weaponEquipped()):
		play_melee_animation()
		await get_tree().create_timer(.45).timeout
	duringAction = false

func play_melee_animation():
	var attackType = RandomNumberGenerator.new().randi_range(0, 1)
	if direction_facing == RIGHT:
		WEAPON.flip_h = false
		SHIELD.flip_h = false
		if attackType == 1:
			ANIMATION.play("attack_side")
		else:
			ANIMATION.play("attack_side_2")
	elif direction_facing == LEFT:
		WEAPON.flip_h = true
		SHIELD.flip_h = true
		if attackType == 1:
			ANIMATION.play("attack_side")
		else:
			ANIMATION.play("attack_side_2")
	elif direction_facing == UP:
		if attackType == 1:
			ANIMATION.play("attack_back")
		else:
			ANIMATION.play("attack_back_2")
	elif direction_facing == DOWN:
		if attackType == 1:
			ANIMATION.play("attack_front")
		else:
			ANIMATION.play("attack_front_2")

func play_ranged_animation():
	BOW.visible = true
	WEAPON.visible = false
	SHIELD.visible = false
	if direction_facing == RIGHT:
		SKIN.flip_h = false
		BOW.flip_h = false
		ANIMATION.play("bow_side")
	elif direction_facing == LEFT:
		SKIN.flip_h = true
		BOW.flip_h = true
		ANIMATION.play("bow_side")
	elif direction_facing == UP:
		ANIMATION.play("bow_back")
	elif direction_facing == DOWN:
		ANIMATION.play("bow_front")
	await get_tree().create_timer(.5).timeout
	BOW.visible = false
	WEAPON.visible = true
	SHIELD.visible = true

While I haven’t looked at your code closely, you could have a key rollover, ghosting, or jamming issue.

See this article for additional details. And, these (and other similar) keyboard test sites to visualize any potential issues:

https://www.microsoft.com/applied-sciences/projects/anti-ghosting-demo
Online Key Rollover Test - Mechanical Keyboard

jgodfrey | 2023-05-12 18:51

Ah, if the problem is ONLY with the ranged attack, than I assume it’s not what I mentioned above. Another question. Are the e and f keys intentionally handled differently (with respect to pressed vs just_pressed?

if Input.is_action_just_pressed("e"):
    print("e")
    attack(true)
elif Input.is_action_pressed("f"):
    print("f")
    attack(false)

You might want to add some print statements in attack() and play_ranged_animation() (and any place else that makes sense) to see if that code is being executed as expected when traveling NE.

Really, with some surgically placed print calls, you should be able to diagnose this pretty easily.

jgodfrey | 2023-05-12 21:25

:bust_in_silhouette: Reply From: fiifciia

Thanks for the answer and a hint. It was about ghosting/jamming issue. The input from E button was ignored when W and D was pressed. Changing the action from E to ENTER has solved the issue entirely.

The reason for is_action_pressed() and is_action_just_pressed() was about the mechanics for a melee and ranged action for which I wanted to allow the player to have a continues melee attacks when the button would be pressed but only a singular ranged attack

Thanks a lot for the help!