Working on implementing combo release actions in a way that works reliably.
This commit is contained in:
parent
1d2dcdd693
commit
6af0b1c23a
@ -37,7 +37,22 @@ void UComboManagerComponent::BeginPlay()
|
||||
}
|
||||
|
||||
|
||||
void UComboManagerComponent::ActivateComboInput(const UComboInputAsset *Input)
|
||||
void UComboManagerComponent::HandleComboInput(const UComboInputAsset *Input, const EComboActionTriggerEvent &TriggerEvent)
|
||||
{
|
||||
switch (TriggerEvent)
|
||||
{
|
||||
case EComboActionTriggerEvent::Activated:
|
||||
this->ActivateComboAction(Input);
|
||||
break;
|
||||
case EComboActionTriggerEvent::Released:
|
||||
this->ReleaseComboAction(Input);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void UComboManagerComponent::ActivateComboAction(const UComboInputAsset *Input)
|
||||
{
|
||||
/************ DEBUG ************/
|
||||
for (const TPair<TObjectPtr<const UComboInputAsset>, float> &Pair : this->DEBUG__UnlockTimers)
|
||||
@ -73,16 +88,18 @@ void UComboManagerComponent::ActivateComboInput(const UComboInputAsset *Input)
|
||||
UE_LOG(LogComboManagerComponent, Verbose, TEXT("%s activated"), *ActionData->ComboAction->ActionName.ToString());
|
||||
}
|
||||
// Otherwise, see if we have a fallback we can use.
|
||||
else if (const TObjectPtr<const UComboAction> &ComboAction = *this->FallbackActions.Find(Input))
|
||||
else if (const TObjectPtr<const UComboAction> *ComboAction = this->FallbackActions.Find(Input))
|
||||
{
|
||||
this->ResetCombo();
|
||||
this->BroadcastDelegates(ComboAction, EComboActionTriggerEvent::Activated);
|
||||
UE_LOG(LogComboManagerComponent, Verbose, TEXT("Fallback action %s activated"), *ComboAction->ActionName.ToString());
|
||||
this->BroadcastDelegates(*ComboAction, EComboActionTriggerEvent::Activated);
|
||||
UE_LOG(LogComboManagerComponent, Verbose, TEXT("Fallback action %s activated"), *(*ComboAction)->ActionName.ToString());
|
||||
}
|
||||
// Simply do nothing if there is no action to be performed.
|
||||
// If we haven't found an action to perform, reset the combo and activate using the default start node.
|
||||
else
|
||||
{
|
||||
UE_LOG(LogComboManagerComponent, Verbose, TEXT("No branch found for this action"));
|
||||
this->ActiveNode = nullptr;
|
||||
this->ActivateComboAction(Input);
|
||||
return;
|
||||
}
|
||||
}
|
||||
void UComboManagerComponent::DEBUG__UnlockAction(TObjectPtr<const UComboInputAsset> Unlock)
|
||||
@ -92,6 +109,26 @@ void UComboManagerComponent::DEBUG__UnlockAction(TObjectPtr<const UComboInputAss
|
||||
Subsystem->UnlockComboInput(Unlock);
|
||||
}
|
||||
|
||||
void UComboManagerComponent::ReleaseComboAction(const class UComboInputAsset *Input)
|
||||
{
|
||||
const TObjectPtr<const UComboSequenceNode> CurrentNode = (this->ActiveNode ? this->ActiveNode : this->DefaultStartNode);
|
||||
checkf(CurrentNode, TEXT("No combo sequence nodes available."));
|
||||
|
||||
const FComboSequenceAction *ActionData = CurrentNode->ComboBranch.Find(Input);
|
||||
// If this node has an action we can release, then release it.
|
||||
if (ActionData && ActionData->ComboAction)
|
||||
{
|
||||
this->BroadcastDelegates(ActionData->ComboAction, EComboActionTriggerEvent::Released);
|
||||
UE_LOG(LogComboManagerComponent, Verbose, TEXT("%s released"), *ActionData->ComboAction->ActionName.ToString());
|
||||
}
|
||||
// Otherwise, see if we have a fallback we can use.
|
||||
else if (const TObjectPtr<const UComboAction> *ComboAction = this->FallbackActions.Find(Input))
|
||||
{
|
||||
this->BroadcastDelegates(*ComboAction, EComboActionTriggerEvent::Released);
|
||||
UE_LOG(LogComboManagerComponent, Verbose, TEXT("Fallback action %s released"), *(*ComboAction)->ActionName.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void UComboManagerComponent::BeginNodeTransition(const UComboSequenceNode *NextNode)
|
||||
{
|
||||
|
||||
@ -19,7 +19,7 @@ void UInputBufferLocalPlayerSubsystem::Initialize(FSubsystemCollectionBase &Coll
|
||||
void UInputBufferLocalPlayerSubsystem::AttachComboManager(UComboManagerComponent *ComboManager, UEnhancedInputComponent *InputComponent)
|
||||
{
|
||||
// Get the player character and try to connect to its combo manager.
|
||||
this->NewComboInput.BindUObject(ComboManager, &UComboManagerComponent::ActivateComboInput);
|
||||
this->OnNewComboInput.BindUObject(ComboManager, &UComboManagerComponent::HandleComboInput);
|
||||
|
||||
// Get all unique EnhancedInput actions bound to combo input actions.
|
||||
const UInputBufferSubsystemGlobalSettings *Settings = GetDefault<UInputBufferSubsystemGlobalSettings>();
|
||||
@ -82,10 +82,12 @@ void UInputBufferLocalPlayerSubsystem::ActivateComboInput(const UComboInputAsset
|
||||
// overwriting a previous combo input with a multi-press combo input.
|
||||
if (bNewSupercedesActive || !bNewInputLocked)
|
||||
{
|
||||
// Set the combo input as active.
|
||||
this->InputBufferActive = ComboInput;
|
||||
|
||||
// If we have inputs to lock, prepare the buffer.
|
||||
if (!ComboInput->LockedComboInputs.IsEmpty())
|
||||
{
|
||||
// Set the combo input as active, and copy its lock data.
|
||||
this->InputBufferActive = ComboInput;
|
||||
this->LockedComboInputs = ComboInput->LockedComboInputs;
|
||||
|
||||
this->InputBufferHold = nullptr;
|
||||
@ -97,7 +99,7 @@ void UInputBufferLocalPlayerSubsystem::ActivateComboInput(const UComboInputAsset
|
||||
UE_LOG(LogInputBufferLocalPlayerSubsystem, Verbose, TEXT("%s is active and won't lock inputs."), *ComboInput->ComboInputName.ToString());
|
||||
}
|
||||
|
||||
this->NewComboInput.Execute(ComboInput);
|
||||
this->OnNewComboInput.Execute(ComboInput, EComboActionTriggerEvent::Activated);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -147,6 +149,14 @@ void UInputBufferLocalPlayerSubsystem::UnlockComboInput(const UComboInputAsset *
|
||||
|
||||
void UInputBufferLocalPlayerSubsystem::ExpireAction(const FInputActionValue &Value, const class UInputAction *Action)
|
||||
{
|
||||
// Only send a release event if we haven't already, i.e. if the combo input associated
|
||||
// with the action is not already buffered for another future activation.
|
||||
if (this->InputBufferActive && this->InputBufferActive != this->InputBufferHold && this->InputBufferActive->MatchesInputAction(Action))
|
||||
{
|
||||
this->OnNewComboInput.Execute(this->InputBufferActive, EComboActionTriggerEvent::Released);
|
||||
}
|
||||
|
||||
// Prepare to expire any buffered combo inputs
|
||||
this->ExpiringActions.Add(Action);
|
||||
const UInputBufferSubsystemGlobalSettings *Settings = GetDefault<UInputBufferSubsystemGlobalSettings>();
|
||||
this->GetWorld()->GetTimerManager().SetTimer(this->InputReleaseExpirationTimerHandle, this, &UInputBufferLocalPlayerSubsystem::ExpireBufferedActions, Settings->InputReleaseExpirationTimerLength);
|
||||
|
||||
@ -45,7 +45,7 @@ public:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void ActivateComboInput(const class UComboInputAsset *Input);
|
||||
void HandleComboInput(const class UComboInputAsset *Input, const EComboActionTriggerEvent &TriggerEvent);
|
||||
|
||||
void BindAction(UObject *ObjectToBindTo, FName FunctionName, const class UComboAction *ComboAction, const EComboActionTriggerEvent &TriggerEvent)
|
||||
{
|
||||
@ -66,8 +66,8 @@ protected:
|
||||
UPROPERTY(BlueprintReadOnly, EditDefaultsOnly)
|
||||
FComboOffsetMap OffsetMap;
|
||||
|
||||
// A list of inputs to map to actions by default. If the active combo sequence node
|
||||
// doesn't handle this action, this list will be used as a fallback whenever possible.
|
||||
// A list of default input->action mappings. If you wish for an action to be handled
|
||||
// outside the scope of a combo sequence node, it should go here.
|
||||
UPROPERTY(BlueprintReadOnly, EditDefaultsOnly)
|
||||
TMap<TObjectPtr<const class UComboInputAsset>, TObjectPtr<const class UComboAction>> FallbackActions;
|
||||
|
||||
@ -78,6 +78,9 @@ protected:
|
||||
FComboActionHandlerDelegate OnComboAction;
|
||||
|
||||
private:
|
||||
void ActivateComboAction(const class UComboInputAsset *Input);
|
||||
void ReleaseComboAction(const class UComboInputAsset *Input);
|
||||
|
||||
void BeginNodeTransition(const class UComboSequenceNode *NextNode);
|
||||
void FinishTransition();
|
||||
void ResetCombo();
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogInputBufferLocalPlayerSubsystem, Log, All);
|
||||
|
||||
DECLARE_DELEGATE_OneParam(FNewComboInput, const class UComboInputAsset*);
|
||||
DECLARE_DELEGATE_TwoParams(FNewComboInput, const class UComboInputAsset*, const EComboActionTriggerEvent &);
|
||||
|
||||
|
||||
/**
|
||||
@ -52,7 +52,7 @@ private:
|
||||
TSet<const class UInputAction*> MostRecentActions;
|
||||
TSet<const class UInputAction*> ExpiringActions;
|
||||
|
||||
FNewComboInput NewComboInput;
|
||||
FNewComboInput OnNewComboInput;
|
||||
|
||||
FTimerHandle MultiPressTimerHandle;
|
||||
FTimerHandle InputReleaseExpirationTimerHandle;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user