Help with "MultiKey" Actions - Character can Only Do certain Actions standing still?

So I have been having issues with multikey support. I looked at the latest “Perfect Doge” and many other sample projects and replicated each version and still my character cant “Dash” when the directional key is being held.

Note: I am using a variable to determine which action to initiate from certain actions

Now if somebody could tell me why….I cant initiate a dash when walking aka pressing key + dash

ex:

Player_Still ——————→ PlayerWalking —————–> “Player_Still_Shortcut”

“Player_Still_Shortcut” ——————> PlayerDashing //Can dash from standing still

“Player_Walking_Shortcut” ————→ PlayerDashing //Cant dash if I am in Walking?

PlayerActionValues:

0 => Standing Still

PlayerActionValues >0 And PlayerActionValues<5 => “Player Walks”

Player Action Value = 6 //Makes player Dash if Standing Still, but not if in walking even tho in my console value 6 is currently being called.

Sorry if I am info dumping I just don’t get why even with just straight up numbers and no key presses I still can’t walk + Dash at the same time only standing still…..

Can I see your script that is sending the arguments?

If it is easier you can also zip your project and send it into pgmmv-support@gotchagotcha.jp so we can investigate it more thoroughly.

Sure here is what I am using and this script is working its just an input manager for node that sends a value to visual script to detect action_values

SO for now in my visual script 1<5 = Walking

0 => Not Walking

6 => Dash

Its in Line #76

playerAction.emit(input.action, input.value)
extends Node

#calling -> Player1_Base->GameObject
@onready var player:GameObject = $".."

signal playerAction(action_name: String, action_value: float)

var buffer_time := 0.3       # Seconds input stays buffered
var combo_time_limit := 0.3  # Max seconds between combo inputs

var input_buffer := []       # Buffered inputs [{action, value, time}]
var input_history := []      # Recent inputs for combo detection [{action, time}]
var last_actions := {}
var combo_triggered := false
var can_accept_input := true

var action_values := {
	"Key_Up": 1.0,
	"Key_Down": 2.0,
	"Key_Left": 3.0,
	"Key_Right": 4.0,
	"Key_Action": 5.0,
	"Key_Dash": 6.0,
	"Key_Attack": 7.0
}

var combo_sequence := ["Key_Dash", "Key_Attack"]

func _ready() -> void:
	var timer = Timer.new()
	timer.name = "CooldownTimer"
	timer.wait_time = 0.5
	timer.one_shot = true
	timer.connect("timeout", Callable(self, "_on_cooldown_timeout"))
	add_child(timer)

func _process(delta: float) -> void:
	read_new_inputs()
	process_buffered_inputs()
	check_timed_combo()

	# Emit No_Input if no keys pressed and buffer empty
	var any_input_pressed = false
	for action_name in action_values.keys():
		if Input.is_action_pressed(action_name):
			any_input_pressed = true
			break
	
	if not any_input_pressed and input_buffer.size() == 0 and can_accept_input:
		playerAction.emit("No_Input", 0)

func read_new_inputs() -> void:
	for action_name in action_values.keys():
		if Input.is_action_just_pressed(action_name):
			var now = Time.get_ticks_msec() / 1000.0
			input_buffer.append({
				"action": action_name,
				"value": action_values[action_name],
				"time": now
			})
			input_history.append({
				"action": action_name,
				"time": now
			})
			print("Buffered Input: ", action_name)

func process_buffered_inputs() -> void:
	var now = Time.get_ticks_msec() / 1000.0

	input_buffer = input_buffer.filter(func(entry):
		return now - entry.time <= buffer_time
	)

	if can_accept_input and input_buffer.size() > 0:
		var input = input_buffer.pop_front()
		playerAction.emit(input.action, input.value)
		print("🟢 Buffered Action Executed: ", input.action, " : ", input.value)

		can_accept_input = false
		$CooldownTimer.start()

func _on_cooldown_timeout() -> void:
	can_accept_input = true
	combo_triggered = false

func check_timed_combo() -> void:
	if combo_triggered:
		return

	var now = Time.get_ticks_msec() / 1000.0

	input_history = input_history.filter(func(entry):
		return now - entry.time <= combo_time_limit
	)

	var recent_sequence = input_history.map(func(entry): return entry.action)

	if recent_sequence.size() >= combo_sequence.size():
		var recent_tail = recent_sequence.slice(-combo_sequence.size(), recent_sequence.size())
		if recent_tail == combo_sequence:
			playerAction.emit("Combo_Spin", 10.0)
			print("🔥 Timed Combo Activated: Spin Attack!")
			combo_triggered = true
			input_history.clear()

Hard to debug without the full project in my hands but I would start with some debugs here:

func process_buffered_inputs() -> void:
	var now = Time.get_ticks_msec() / 1000.0

	input_buffer = input_buffer.filter(func(entry):
		return now - entry.time <= buffer_time
	)

	print("Before pop: ",input_buffer)

	if can_accept_input and input_buffer.size() > 0:
		var input = input_buffer.pop_front()
		playerAction.emit(input.action, input.value)
		print("🟢 Buffered Action Executed: ", input.action, " : ", input.value)

		can_accept_input = false
		$CooldownTimer.start()
	
	print("After pop: ",input_buffer)

I’m curious if the movement input is still first out, so all that is popping is the movement input.

Well not to sure where to start in debugging myself anyhow I just sent the project files to that support email you mentioned earlier hope you guys can figure out why I can’t use “multiple keys at once”.

「いいね!」 1

We were able to solve the issue. For anyone reading and wondering similar thing this is what was happening:

  • Walk → Idle link was created first priority 0
  • Walk → Dash link was created second priority 0
  • Both link conditions were true at same time and since both conditions were priority 0, Walk → Idle took priority (because it was created first)
  • By changing the Walk → Dash link priority to 1 (higher priority), it let that link get checked first, making it work as intended

「いいね!」 1

Once again the link condition priority issue rears its head. I’ll make a reminder post about it later on the official Twitter account too.

「いいね!」 2