@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