As flurick mentioned, Input Map does not check all other actions if they overlap. One of the main benefits (to me at least) of the Input Map is allowing the user to create custom mappings. However, in this setup we don’t know ahead of time which actions will have key modifiers.
One common scenario I can think of is selection control. Suppose you want to have controls to cycle your selection through various possible targets. Your default mapping is to use E to increment through possible targets and Q to decrement. Then the user changes the mapping to be Tab for increment and Shift+Tab to decrement.
In the default mapping you would not check for modifiers. After the user changes the mapping then Tab will work fine but Shift+Tab will both increment and decrement, leaving the selection as if nothing had happened. It seems the only way to handle this scenario is to check to make sure modifier key states match whatever is assigned to the input action.
To solve this, I add this function to be available to input processors:
func _check_modifiers_match(event: InputEvent, action: String) -> bool:
if not event is InputEventWithModifiers: return true
for e in InputMap.get_action_list(action):
if e is InputEventWithModifiers:
if e.alt == event.alt and \
e.command == event.command and \
e.control == event.control and \
e.meta == event.meta and \
e.shift == event.shift:
This function returns true unless the event is a type with modifiers and the modifiers do not match any of the mappings assigned to associated action. Note that this does not check to make sure keys other than the modifiers do not match. This function should only be called after you are sure you have the right action.
Here is how you would invoke the function:
if event.is_action_pressed("cycle_selection_forward") and _check_modifiers_match(event, "cycle_selection_forward"):
# increment selection
if event.is_action_pressed("cycle_selection_backward") and _check_modifiers_match(event, "cycle_selection_backward"):
# decrement selection
Basically, check if the action is in the state you want and that the modifiers match. Do this for all actions. Note that this will block actions that you want to do regardless of modifiers. Perhaps you have some movement related actions that you want to perform no matter what modifiers are done. Simply don’t include this check for those actions.
I haven’t tested this thoroughly, but it has worked well for me so far. Please let me know how it goes if you try it out!