tool extends HBoxContainer export(String) var action_name = "" export(String) var description = "Lorem ipsum." export(String) var config_file = "user://input.cfg" func _enter_tree(): if not self.has_node( "description" ): var new_label = Label.new() new_label.name = "description" new_label.text = description new_label.align = HALIGN_RIGHT new_label.size_flags_horizontal = SIZE_EXPAND_FILL new_label.size_flags_vertical = SIZE_EXPAND self.add_child( new_label ) new_label.set_owner( self ) if not self.has_node( "keyboard" ): var new_button = Button.new() new_button.name = "keyboard" new_button.align = HALIGN_LEFT new_button.size_flags_horizontal = SIZE_EXPAND_FILL new_button.size_flags_vertical = SIZE_EXPAND self.add_child( new_button ) new_button.set_owner( self ) # if not self.has_node( "joypad" ): var new_button_joypad = Button.new() new_button_joypad.name = "joypad" new_button_joypad.align = HALIGN_LEFT new_button_joypad.size_flags_horizontal = SIZE_EXPAND_FILL new_button_joypad.size_flags_vertical = SIZE_EXPAND self.add_child( new_button_joypad ) new_button_joypad.set_owner( self ) func get_event_with_modifier_from_string( scancode, type ): if type == "keyboard": var new_event = InputEventKey.new() if not scancode.find( "Meta" ) == -1: new_event.meta = true if not scancode.find( "Control" ) == -1: new_event.control = true if not scancode.find( "Alt" ) == -1: new_event.alt = true if not scancode.find( "Shift" ) == -1: new_event.shift = true if not scancode.findn( "+" ) == -1: scancode = scancode.right(scancode.find_last( "+" )+1) new_event.scancode = OS.find_scancode_from_string( scancode ) return new_event elif type == "joypad": var new_event = InputEventJoypadButton.new() new_event.button_index = Input.get_joy_button_index_from_string( scancode ) return new_event return null func load_from_config(): var config = ConfigFile.new() var err = config.load( config_file ) if err:# Assuming that file is missing, generate default config for event in InputMap.get_action_list( action_name ): if event is InputEventKey: var scancode = OS.get_scancode_string( event.get_scancode_with_modifiers() ) config.set_value("keyboard", action_name, scancode) elif event is InputEventJoypadButton: var joy_button_name = Input.get_joy_button_string( event.button_index ) config.set_value("joypad", action_name, joy_button_name) config.save( config_file ) else: var action_found = false for action in config.get_section_keys("keyboard"): if action == action_name: action_found = true var event = get_event_with_modifier_from_string( config.get_value("keyboard", action_name), "keyboard") for old_event in InputMap.get_action_list( action_name ): if old_event is InputEventKey: InputMap.action_erase_event(action_name, old_event) InputMap.action_add_event(action_name, event) break if not action_found: for event in InputMap.get_action_list( action_name ): if event is InputEventKey: var scancode = OS.get_scancode_string( event.get_scancode_with_modifiers() ) config.set_value("keyboard", action_name, scancode) action_found = false for action in config.get_section_keys("joypad"): if action == action_name: action_found = true var event = get_event_with_modifier_from_string( config.get_value("joypad", action_name), "joypad") for old_event in InputMap.get_action_list( action_name ): if old_event is InputEventJoypadButton: InputMap.action_erase_event(action_name, old_event) InputMap.action_add_event(action_name, event) if not action_found: for event in InputMap.get_action_list( action_name ): if event is InputEventJoypadButton: var joy_button_name = Input.get_joy_button_string( event.button_index ) config.set_value("joypad", action_name, joy_button_name) config.save( config_file ) func save_to_config(section, key, value): var config = ConfigFile.new() var err = config.load( config_file ) if err: print("Error code when loading config file: ", err) else: config.set_value(section, key, value) config.save( config_file ) # Input management func wait_for_input(): set_process_input(true) # Input management func _input(event): if event is InputEventKey and not event.pressed and not event.is_echo(): var input_string = OS.get_scancode_string( event.scancode ) if not event.is_action("ui_cancel") \ and not input_string == "Meta" \ and not input_string == "Control" \ and not input_string == "Alt" \ and not input_string == "Shift" \ : get_tree().set_input_as_handled() set_process_input( false ) $keyboard.text = "" if event.meta: $keyboard.text += "Meta+" if event.control: $keyboard.text += "Control+" if event.alt: $keyboard.text += "Alt+" if event.shift: $keyboard.text += "Shift+" $keyboard.text += input_string for old_event in InputMap.get_action_list( action_name ): if old_event is InputEventKey: InputMap.action_erase_event(action_name, old_event) InputMap.action_add_event(action_name, event) save_to_config("keyboard", action_name, $keyboard.text) elif event is InputEventJoypadButton and not event.pressed and not event.is_echo(): var input_string = Input.get_joy_button_string( event.button_index ) get_tree().set_input_as_handled() set_process_input( false ) $joypad.text = input_string for old_event in InputMap.get_action_list( action_name ): if old_event is InputEventJoypadButton: InputMap.action_erase_event(action_name, old_event) InputMap.action_add_event(action_name, event) save_to_config("joypad", action_name, $joypad.text) func _ready(): load_from_config() for event in InputMap.get_action_list( action_name ): if event is InputEventKey: $keyboard.text = OS.get_scancode_string( event.get_scancode_with_modifiers() ) elif event is InputEventJoypadButton: $joypad.text = Input.get_joy_button_string( event.button_index ) $keyboard.connect( "pressed", self, "wait_for_input" ) $joypad.connect( "pressed", self, "wait_for_input" ) set_process_input(false)