Fixed a bug that can cause buttons not mapped to combo inputs to block later combo inputs when they aren't part of a multi-press.

This commit is contained in:
Jamie Greunbaum 2023-10-11 01:20:29 -04:00
parent b77a9bd2ed
commit a9a841911a
2 changed files with 35 additions and 6 deletions

View File

@ -59,20 +59,47 @@ void UInputBufferComponent::InitializeComponent()
void UInputBufferComponent::AddActionToBuffer(const FInputActionValue &Value, const class UInputAction *Action) void UInputBufferComponent::AddActionToBuffer(const FInputActionValue &Value, const class UInputAction *Action)
{ {
this->MostRecentActions.Add(Action); this->MultiPressActions.Add(Action);
this->ExpiringActions.Remove(Action); this->ExpiringActions.Remove(Action);
// Find any combo input that matches this action, plus buffered actions. // Find any combo input that matches this action, plus buffered actions.
bool bComboInputFound = false;
for (TObjectPtr<const UComboInputAsset> ComboInput : this->ComboInputList) for (TObjectPtr<const UComboInputAsset> ComboInput : this->ComboInputList)
{ {
if (ComboInput->MatchesInputActions(this->MostRecentActions)) if (ComboInput->MatchesInputActions(this->MultiPressActions))
{ {
this->ActivateComboInput(ComboInput.Get()); this->ActivateComboInput(ComboInput.Get());
bComboInputFound = true;
break; break;
} }
} }
// If we haven't found any matching inputs, check if anything was somehow unhandled.
// This can happen if, for example, a jump input can combine with an attack input to
// create a combo action, but jump by itself has no action on its own.
if (!bComboInputFound)
{
if (!this->UnhandledActions.IsEmpty())
{
TSet<const UInputAction*> HandledActions = this->MultiPressActions;
for (const UInputAction *UnhandledAction : this->UnhandledActions)
{
HandledActions.Remove(UnhandledAction);
}
for (TObjectPtr<const UComboInputAsset> ComboInput : this->ComboInputList)
{
if (ComboInput->MatchesInputActions(HandledActions))
{
this->ActivateComboInput(ComboInput);
bComboInputFound = true;
break;
}
}
}
this->UnhandledActions.Add(Action);
}
const UInputBufferGlobalSettings *Settings = GetDefault<UInputBufferGlobalSettings>(); const UInputBufferGlobalSettings *Settings = GetDefault<UInputBufferGlobalSettings>();
this->GetWorld()->GetTimerManager().SetTimer(this->MultiPressTimerHandle, this, &UInputBufferComponent::ClearMultiPresses, Settings->MultiPressTimerLength); this->GetWorld()->GetTimerManager().SetTimer(this->MultiPressTimerHandle, this, &UInputBufferComponent::ClearMultiPresses, Settings->MultiPressTimerLength);
} }
@ -80,13 +107,14 @@ void UInputBufferComponent::ClearMultiPresses()
{ {
#if WITH_EDITOR #if WITH_EDITOR
TArray<FString> ActionNames; TArray<FString> ActionNames;
for (const UInputAction *Action : this->MostRecentActions) for (const UInputAction *Action : this->MultiPressActions)
{ {
ActionNames.Add(Action->GetName()); ActionNames.Add(Action->GetName());
} }
UE_LOG(LogInputBufferComponent, Verbose, TEXT("Multi-press buffer cleared (%s)"), *FString::Join(ActionNames, TEXT(" | "))); UE_LOG(LogInputBufferComponent, Verbose, TEXT("Multi-press buffer cleared (%s)"), *FString::Join(ActionNames, TEXT(" | ")));
#endif #endif
this->MostRecentActions.Empty(); this->MultiPressActions.Empty();
this->UnhandledActions.Empty();
} }
void UInputBufferComponent::ActivateComboInput(const UComboInputAsset *ComboInput) void UInputBufferComponent::ActivateComboInput(const UComboInputAsset *ComboInput)

View File

@ -53,7 +53,8 @@ private:
// A local backup of the global setting containing the list of combo inputs to respond to. // A local backup of the global setting containing the list of combo inputs to respond to.
TSet<TObjectPtr<const UComboInputAsset>> ComboInputList; TSet<TObjectPtr<const UComboInputAsset>> ComboInputList;
TSet<const class UInputAction*> MostRecentActions; TSet<const class UInputAction*> MultiPressActions;
TSet<const class UInputAction*> UnhandledActions;
TSet<const class UInputAction*> ExpiringActions; TSet<const class UInputAction*> ExpiringActions;
FNewComboInput OnNewComboInput; FNewComboInput OnNewComboInput;