High-Flexibility Input Remapping Framework for Godot 4.5+
- Professional-grade input logic and UI generation.
- Decoupled architecture for maximum project flexibility.
- Full support for Keyboard, Mouse, and Gamepad hardware.
- Godot 4.5+
- Multi-Slot Mapping: Support for up to 3 binding slots per action.
- Vector2 Support: Automated generation of directional sub-actions (WASD/Sticks).
- Modifier Combos: Native detection for Shift, Ctrl, Alt, and Meta combinations.
- Visual Icons: Optional icon library support for visual button prompts.
- Dynamic Search: Filter actions by name, category, ID, or bound key in real-time.
- Automatic UI: One-click generation of fully functional, searchable remap menus.
- Whitelist/Blacklist: Restrict remapping to specific keys or buttons.
- Custom Validators: Assign a Callable for deep validation logic.
- Toggle Mode: Option to make actions persistent (press to start, press again to stop).
- Automatic Saving: State is automatically committed to disk when the menu is hidden or closed.
- Place the SmartInput folder in
res://addons/smartinput/. - Enable the plugin in Project Settings -> Plugins.
- The
InputControllerautoload will be created automatically.
- Create a new
InputActionsListresource (e.g.,controls.tres). - Add actions to the
Actionsarray. Choose Press for buttons or Vector 2 for movement. - Assign this resource to the controller in your game's init script:
func _ready() -> void: InputController.input_actions = load("res://controls.tres")
- Create a
VBoxContainerin your UI scene. - Add it to a Node Group named "SettingsMenu".
- Call the population function:
Note: This automatically injects a Search Bar and organizes actions into categories.
InputController.populate_group("SettingsMenu")
Warning
Do not attach custom scripts directly to the SettingsMenu VBoxContainer. The plugin attaches an internal SmartInputSaver node to handle automatic saving. If you need custom logic, attach your script to a parent node instead.
You can configure these via InputController.Namespace.property (e.g., InputController.SettingsMenu.show_search = false) or by modifying the InputConfig class in globals.gd.
show_search(bool): Toggle search bar visibility.search_placeholder(String): Placeholder text for the search bar.column_titles(Array[String]): Titles for the binding columns.show_column_headers(bool): Toggle "ACTION PRIMARY..." header row.show_category_headers(bool): Toggle category labels.show_action_headers(bool): Toggle base titles for Vector2 actions.show_separators(bool): Toggle HSeparators between categories.show_restore_defaults(bool): Toggle visibility of the restore button.show_revert_changes(bool): Toggle visibility of the revert button.restore_label(String): Text shown on the restore button.revert_label(String): Text shown on the revert button.label_stretch_ratio(float): Width ratio for action labels.button_stretch_ratio(float): Width ratio for binding buttons.
keybind_scene_override(PackedScene): Custom scene for individual keybind rows.category_header_scene(PackedScene): Custom scene for category titles.action_header_scene(PackedScene): Custom scene for vector action headers.column_header_scene(PackedScene): Custom scene for the column title row.search_bar_scene(PackedScene): Custom scene replacing the search bar.footer_scene(PackedScene): Custom scene replacing the footer area.
Keybind.remapping_text(String): Text shown while waiting for input.Keybind.unbound_text(String): Text shown for empty slots.InputAction.category(String): Default category for new actions.InputAction.deadzone(float): Default deadzone (0.5).InputAction.device_limit(int): 0 = Both, 1 = Keyboard Only, 2 = Controller Only.InputAction.multi_click_window(float): Time window for double/triple clicks (Default: 0.25).InputAction.multi_click_delayed(bool): If true, delays double-click emission to ensure exclusivity with triple-clicks (Default: true).InputAction.up_display_name / down_ / left_ / right_(String): Default labels for directions.InputAction.up_suffix / down_ / left_ / right_(String): Suffixes for InputMap actions.
InputController.get_vector(id: String) -> Vector2: Gets movement (WASD/Joystick).InputController.is_held(id: String) -> bool: Checks if an action is pressed.InputController.is_just_pressed(id: String) -> bool: Checks if an action was hit this frame.InputController.is_double_clicked(id: String) -> bool: Checks if an action was double-tapped this frame.InputController.is_triple_clicked(id: String) -> bool: Checks if an action was triple-tapped this frame.
input_actions(InputActionsList): The resource containing your action definitions.save_path(String): Path for user bindings (default:user://input_config.cfg).use_pretty_names(bool): Converts indices (Joy 0) to names (Button A).show_conflicts(bool): Highlights conflicting bindings in red.unbind_inputs(Array): Inputs that trigger an unbind (default: Delete/RightClick).set_bindings_count(int): Sets columns shown (1-3).save_config(): Manually commits current bindings to the save file.revert_changes(): Reloads bindings from the save file (undoes unsaved changes).restore_defaults(): Resets all bindings to resource defaults.keybind_scene(PackedScene): Global default row scene.modal_scene(PackedScene): Optional scene for "Press any key" popup.icon_library(Resource): ActiveInputIconresource.
lock_action(id, locked, dir): Disables an entire row.hide_action(id, dir): Hides an action from the UI menu dynamically.unhide_action(id, dir): Forces a hidden action to be visible.is_action_hidden(id, dir) -> bool: Checks if an action is currently hidden.set_action_toggle(id, enabled, dir): Sets whether an action behaves as a toggle.is_action_toggle(id, dir) -> bool: Checks if an action is currently in toggle mode.block_slot(id, index, blocked, dir): Disables a specific column for an action.block_category(cat)/unblock_category(cat): Hides/disables an entire category.whitelist_inputs(id, list, dir): Only allow specific keys/buttons.blacklist_inputs(id, list, dir): Prevent specific keys from being bound.validator_func: Custom validation:func(id, event, [dir]) -> bool.
id(StringName): Unique action identifier.display_name(String): User-friendly label.category(String): Grouping for the menu.behavior(Enum): Press or Vector 2.is_locked(bool): Hard-lock the action in the UI.is_hidden(bool): Hide the action from the UI menu by default.is_toggle(bool): Makes the action toggle on/off instead of requiring a hold.blocked_indices(Array[int]): Indices of columns to disable.custom_row_scene(PackedScene): Visual override for this specific action.device_limit(Enum): Restrict hardware type for this action.
keyboard_icons_path(String): Folder for keyboard glyphs.mouse_icons_path(String): Folder for mouse glyphs.gamepad_icons_path(String): Folder for controller glyphs.manual_overrides(Dictionary): Map specific key names to Texture2Ds.
Name files in lowercase using underscores (e.g., space.png, mouse_1.png, joy_button_0.png).
- action_pressed(id) / action_released(id)
- action_double_clicked(id) / action_triple_clicked(id)
- device_changed(is_controller): Emitted when hardware changes.
- bindings_updated: Emitted when keys change or defaults restored.
- request_menu_build: Triggers a UI refresh.
- remapping_started(id, index) / remapping_finished(id, index, event)
Boost Software License 1.0. Use it in any project without credit, but keep the license in source files.