“MultiKey” 操作帮助 - 角色只能在静止时执行某些操作?

所以我一直遇到多键支持的问题。我查看了最新的“完美狗狗”以及其他许多示例项目,并复制了每个版本,但我的角色在按住方向键时仍然无法“冲刺”。

注意:我使用一个变量来确定从某些动作中启动哪个动作

现在如果有人能告诉我为什么……当我在行走时(即按下移动键 + 冲刺键),我无法启动冲刺

例如:

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。

如果我信息过载了请见谅,我只是不明白为什么即使只是直接使用数字而不按任何键,我仍然无法在行走时同时冲刺,只能在静止站立时做到……

我能看看你发送参数的脚本吗?

如果更方便的话,你也可以将项目压缩后发送到 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
	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("🟢 已执行缓冲操作:", input.action, " : ", input.value)

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

我很好奇移动输入是否仍然是先进先出,因此弹出的所有操作都是移动输入。

不太确定从哪里开始调试,不过我已经把项目文件发送到了您之前提到的支持邮箱,希望你们能找出为什么我无法“同时使用多个密钥”。

1 个赞

我们成功解决了该问题。对于正在阅读并遇到类似情况的任何人,以下是当时发生的情况:

  • 首先创建了“行走 → 待机”链接,优先级为 0
  • 随后创建了“行走 → 冲刺”链接,优先级为 0
  • 两个链接的条件同时为真,由于两者优先级均为 0,“行走 → 待机”链接优先(因为它先被创建)
  • 将“行走 → 冲刺”链接的优先级更改为 1(更高优先级)后,该链接得以优先检查,从而按预期工作

1 个赞

链接条件优先级问题再次出现。我稍后也会在官方 Twitter 账号上发布提醒帖子。

2 个赞