tool extends HBoxContainer #export(String) var action_name = "" export(String) var description = "Lorem ipsum." export(String) var config_file = "user://input.cfg" export(String) var default_keyboard export(String) var default_keyboard_alt export(String) var default_joypad var action_name var current_keyboard func _ready(): action_name = self.name current_keyboard = $keyboard load_from_config() var key_found = false var key_alt_found = false for event in InputMap.get_action_list( action_name ): if event is InputEventKey: pass if not key_found: $keyboard.text = OS.get_scancode_string( event.get_scancode_with_modifiers() ) key_found = true elif not key_alt_found: $keyboard_alt.text = OS.get_scancode_string( event.get_scancode_with_modifiers() ) key_alt_found = true elif event is InputEventJoypadButton: $joypad.text = Input.get_joy_button_string( event.button_index ) $keyboard.connect( "pressed", self, "wait_for_input" ) $keyboard_alt.connect( "pressed", self, "wait_for_input_alt" ) $joypad.connect( "pressed", self, "wait_for_input" ) set_process_input(false) 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( "keyboard_alt" ): var new_button = Button.new() new_button.name = "keyboard_alt" 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 config.save( config_file ) else: # on initialise l'entrée, si elle n'existe pas déjà, par la valeur par defaut du projet. if not config.has_section_key("keyboard", action_name): 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) break # on initialise l'entrée alternative, si elle n'existe pas déjà, par la valeur par defaut du projet. var is_first = true if not config.has_section_key("keyboard_alt", action_name): for event in InputMap.get_action_list( action_name ): if not is_first and event is InputEventKey: var scancode = OS.get_scancode_string( event.get_scancode_with_modifiers() ) config.set_value("keyboard_alt", action_name, scancode) break if is_first and event is InputEventKey: is_first = false if not config.has_section_key("joypad", action_name): for event in InputMap.get_action_list( action_name ): if event is InputEventJoypadButton: var scancode = Input.get_joy_button_string( event.button_index ) config.set_value("joypad", action_name, scancode) break # On efface toutes les touches de clavier de l'InputMap correspondants à l'action en cours. for old_event in InputMap.get_action_list( action_name ): if old_event is InputEventKey or old_event is InputEventJoypadButton: InputMap.action_erase_event(action_name, old_event) # on recupere les touches du fichier de config et on les ajoutes à l'input map. if config.has_section("keyboard"): 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") InputMap.action_add_event(action_name, event) break if config.has_section("keyboard_alt"): var action_found = false for action in config.get_section_keys("keyboard_alt"): if action == action_name: action_found = true var event = get_event_with_modifier_from_string( config.get_value("keyboard_alt", action_name), "keyboard") InputMap.action_add_event(action_name, event) break if config.has_section("joypad"): var 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) 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(): current_keyboard = $keyboard set_process_input(true) func wait_for_input_alt(): current_keyboard = $keyboard_alt 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 ) current_keyboard.text = "" if event.meta: current_keyboard.text += "Meta+" if event.control: current_keyboard.text += "Control+" if event.alt: current_keyboard.text += "Alt+" if event.shift: current_keyboard.text += "Shift+" current_keyboard.text += input_string var change_first_key = true if current_keyboard.name == "keyboard_alt": change_first_key = false var is_first_key = true for old_event in InputMap.get_action_list( action_name ): if old_event is InputEventKey: if is_first_key: if change_first_key: InputMap.action_erase_event(action_name, old_event) is_first_key = false elif not change_first_key: InputMap.action_erase_event(action_name, old_event) InputMap.action_add_event(action_name, event) save_to_config(current_keyboard.name, action_name, current_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)