Hold Inputs with CommonUI and Enhanced Input

I just found how to do it.

In FActionRouterBindingCollection::ProcessHoldInput we can see that it need HoldMappings on Bindings.

We can see that FActionRouterBindingCollection::ProcessNormalInput just below support enhanced input. I didn’t found a way to override ProcessHoldInput.

So i just insert my own HoldMapping.

In the OnInputMethodChanged of your UCommonButtonBase child put this :

// Add hold support for enhanced input
if (CommonUI::IsEnhancedInputSupportEnabled() && bRequiresHold && HoldTime > 0)
{
	for (const FUIActionBindingHandle& BindingHandle : GetActionBindings())
	{
		if (TSharedPtr<FUIActionBinding> Binding = FUIActionBinding::FindBinding(BindingHandle); Binding.IsValid() && Binding->InputAction.IsValid())
		{
			if (Binding->InputAction.IsValid())
			{
				if (const UInputAction* InputAction = Binding->InputAction.Get())
				{
					Binding->HoldMappings.Empty();
					
					TArray<FKey> InputActionKeys;
					CommonUI::GetEnhancedInputActionKeys(GetOwningLocalPlayer(), InputAction, InputActionKeys);
					for (const FKey& InputActionKey : InputActionKeys)
					{
						if (!InputActionKey.IsValid())
							return;
						
						const FUIActionKeyMapping KeyMapping(InputActionKey, HoldTime, HoldRollbackTime);
						Binding->HoldMappings.Add(KeyMapping);
					}
				}
			}
		}
	}

I did here because i need mapping context to be set to found every key bound to input action.

You need to add a Hold trigger on your InputAction (I didn’t search why) but value in there are not used. HoldData on your button instead is used (could be changed by overriding UpdateHoldData).

You also need to override NativeOnActionProgress by adding:

CurrentHoldTime = HeldPercent * HoldTime;

To actually have your function call after completion of holding.

2 Likes