「MultiKey」アクションのヘルプ - キャラクターは立ち止まっている時だけ特定のアクションが可能ですか?

マルチキーサポートに問題があります。**「Perfect Doge」**の最新バージョンや他のサンプルプロジェクトを確認し、各バージョンを再現しましたが、方向キーを押しながらキャラクターが「ダッシュ」できません。

注:特定のアクションからどのアクションを開始するかを決定するために変数を使用しています

誰か、なぜそうなるのか教えてください。…歩いている間(キーを押しながらダッシュ)にダッシュを開始できません。

例:

Player_Still ——————→ PlayerWalking —————–→ 「Player_Still_Shortcut」

「Player_Still_Shortcut」 ——————→ PlayerDashing //静止状態からダッシュ可能

「Player_Walking_Shortcut」 ————→ PlayerDashing //歩いている間はダッシュできない?

PlayerActionValues:

0 => 静止状態

PlayerActionValues > 0 かつ PlayerActionValues < 5 => 「Player Walks」

Player Action Value = 6 //静止状態ならダッシュしますが、歩いている状態ではダッシュできません。コンソールでは現在値 6 が呼び出されているにもかかわらずです。

情報過多で申し訳ありませんが、単純な数値のみでキー操作も不要な状況でも、静止状態のみでしか「歩く+ダッシュ」が同時にできない理由がわかりません。

引数を送信しているスクリプトを見せますか?\n\nもし簡単であれば、プロジェクトをzipにしてpgmmv-support@gotchagotcha.jpに送信していただければ、より詳しく調査できます。

はい、私が使用しているものはこれで、このスクリプトは動作しています。これはNode用の入力マネージャーで、action_valuesを検出するためにビジュアルスクリプトに値を送信します。

現在、ビジュアルスクリプトでは以下のように定義されています。

1 < 5 = 歩行

0 = 歩行していない

6 = ダッシュ

これは76行目にあります。

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

# 呼び出し元 -> Player1_Base->GameObject
@onready var player:GameObject = $".."

signal playerAction(action_name: String, action_value: float)

var buffer_time := 0.3       # 入力がバッファリングされる秒数
var combo_time_limit := 0.3  # コンボ入力の間の最大秒数

var input_buffer := []       # バッファリングされた入力 [{action, value, time}]
var input_history := []      # コンボ検出用の最近の入力 [{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()

	# キーが押されておらず、バッファが空の場合、No_Inputをemit
	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("バッファリングされた入力: ", 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("🟢 バッファリングされたアクションが実行されました: ", 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("🔥 タイミングコンボがアクティブになりました: スピンアタック!")
			combo_triggered = true
			input_history.clear()

フルプロジェクトを手元にないためデバッグは難しいですが、まずは以下から始めてみることをお勧めします:

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)

移動入力がまだ最初にポップされるのか、つまりポップされるのは移動入力だけなのか、興味があります。

正直、デバッグのどこから始めればよいか確信が持てませんが、とにかく先ほどおっしゃっていたサポートメールにプロジェクトファイルを送信しました。なぜ「複数のキーを同時に使用できない」のか、ぜひ見つけてください。

「いいね!」 1

問題を解決できました。同様の疑問を持っている方のために、何が起きていたか説明します:

  • Walk → Idle リンクが最初に作成され、優先順位は 0 でした
  • Walk → Dash リンクが次に作成され、優先順位も 0 でした
  • 両方のリンク条件が同時に真となり、両方とも優先順位 0 だったため、最初に作成された Walk → Idle が優先されました
  • Walk → Dash リンクの優先順位を 1(より高い優先順位)に変更したところ、そのリンクが最初にチェックされるようになり、意図した通りに動作するようになりました

「いいね!」 1

再びリンク条件の優先順位の問題が表面化しました。後ほど公式Twitterアカウントでもリマインダーを投稿します。

「いいね!」 2