90 lines
2.8 KiB
GDScript3
90 lines
2.8 KiB
GDScript3
|
|
@tool
|
|||
|
|
extends Resource
|
|||
|
|
class_name ActionProfile
|
|||
|
|
|
|||
|
|
@export var profile_name: String = "Default"
|
|||
|
|
|
|||
|
|
@export var actions: Array[ActionDef] = []
|
|||
|
|
@export var key_bindings: Array[KeyBinding] = []
|
|||
|
|
@export var joy_bindings: Array[JoyAxisBinding] = []
|
|||
|
|
|
|||
|
|
# —— 基础校验:在 Inspector 里点“Validate”用,或运行时装载前自测 ——
|
|||
|
|
func validate_profile() -> Array[String]:
|
|||
|
|
var errors: Array[String] = []
|
|||
|
|
|
|||
|
|
# 1) 动作合法性 & 唯一性
|
|||
|
|
var ids := {}
|
|||
|
|
for a in actions:
|
|||
|
|
if a == null or not a.is_valid():
|
|||
|
|
errors.append("Invalid ActionDef found (empty id or bad kind).")
|
|||
|
|
continue
|
|||
|
|
if ids.has(a.id):
|
|||
|
|
errors.append("Duplicate Action id: %s" % a.id)
|
|||
|
|
else:
|
|||
|
|
ids[a.id] = a.kind
|
|||
|
|
|
|||
|
|
# 2) 键盘绑定合法性 & 指向存在的动作
|
|||
|
|
for kb in key_bindings:
|
|||
|
|
if kb == null or not kb.is_valid():
|
|||
|
|
errors.append("Invalid KeyBinding for action '%s'." % (kb if kb == null else kb.action_id))
|
|||
|
|
continue
|
|||
|
|
if not ids.has(kb.action_id):
|
|||
|
|
errors.append("KeyBinding refers to unknown action '%s'." % kb.action_id)
|
|||
|
|
elif kb.type == "button" and ids[kb.action_id] != "button":
|
|||
|
|
errors.append("KeyBinding(button) mapped to non-button action '%s'." % kb.action_id)
|
|||
|
|
elif kb.type == "axis_pair" and ids[kb.action_id] != "axis":
|
|||
|
|
errors.append("KeyBinding(axis_pair) mapped to non-axis action '%s'." % kb.action_id)
|
|||
|
|
|
|||
|
|
# 3) 手柄轴绑定合法性 & 指向存在的动作
|
|||
|
|
for jb in joy_bindings:
|
|||
|
|
if jb == null or not jb.is_valid():
|
|||
|
|
errors.append("Invalid JoyAxisBinding.")
|
|||
|
|
continue
|
|||
|
|
if not ids.has(jb.action_id):
|
|||
|
|
errors.append("JoyAxisBinding refers to unknown action '%s'." % jb.action_id)
|
|||
|
|
elif ids[jb.action_id] != "axis":
|
|||
|
|
errors.append("JoyAxisBinding mapped to non-axis action '%s'." % jb.action_id)
|
|||
|
|
|
|||
|
|
return errors
|
|||
|
|
|
|||
|
|
# —— 便于 InputComponent 读取的“拍扁”结构(不会创建任何监听,只做数据整形)——
|
|||
|
|
func flatten() -> Dictionary:
|
|||
|
|
# 输出:
|
|||
|
|
# {
|
|||
|
|
# "actions": { id: { "kind": "button"|"axis" } },
|
|||
|
|
# "keys_button": { keycode: [action_id, ...] },
|
|||
|
|
# "keys_axispair": { axis_id: { "neg": keycode|0, "pos": keycode|0 } },
|
|||
|
|
# "joy_axes": { axis_id: { "axis": int, "deadzone": float } }
|
|||
|
|
# }
|
|||
|
|
var out := {
|
|||
|
|
"actions": {},
|
|||
|
|
"keys_button": {},
|
|||
|
|
"keys_axispair": {},
|
|||
|
|
"joy_axes": {}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for a in actions:
|
|||
|
|
if a and a.is_valid():
|
|||
|
|
out.actions[a.id] = { "kind": a.kind }
|
|||
|
|
|
|||
|
|
for kb in key_bindings:
|
|||
|
|
if kb and kb.is_valid():
|
|||
|
|
if kb.type == "button":
|
|||
|
|
if not out.keys_button.has(kb.key):
|
|||
|
|
out.keys_button[kb.key] = []
|
|||
|
|
out.keys_button[kb.key].append(kb.action_id)
|
|||
|
|
elif kb.type == "axis_pair":
|
|||
|
|
out.keys_axispair[kb.action_id] = {
|
|||
|
|
"neg": kb.neg_key,
|
|||
|
|
"pos": kb.pos_key
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for jb in joy_bindings:
|
|||
|
|
if jb and jb.is_valid():
|
|||
|
|
out.joy_axes[jb.action_id] = {
|
|||
|
|
"axis": jb.axis,
|
|||
|
|
"deadzone": jb.deadzone
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return out
|