Components were reworked to no longer need a separate list of valid inputs to listen for.

This commit is contained in:
Jamie Greunbaum 2023-10-04 18:52:53 -04:00
parent 3d0fedabf6
commit 0feb21fefc
4 changed files with 54 additions and 11 deletions

View File

@ -34,6 +34,10 @@ void UComboManagerComponent::InitializeComponent()
void UComboManagerComponent::SetComboGraph(const UComboActionGraph *Graph) void UComboManagerComponent::SetComboGraph(const UComboActionGraph *Graph)
{ {
this->ComboGraph = Graph; this->ComboGraph = Graph;
this->FoundInputsCache.Empty();
this->FindAllUsedInputs();
this->ActiveNode = this->ComboGraph->StartNode; this->ActiveNode = this->ComboGraph->StartNode;
this->PreviousNode = nullptr; this->PreviousNode = nullptr;
} }
@ -149,6 +153,43 @@ void UComboManagerComponent::ResetCombo()
} }
TSet<const UComboInputAsset *> &UComboManagerComponent::FindAllUsedInputs()
{
if (this->FoundInputsCache.IsEmpty())
{
// First check the graph for inputs to respond to.
this->FindAllUsedInputs_RecurseGraph(this->ComboGraph->StartNode, this->FoundInputsCache);
// Next check the fallback actions for supplementary inputs to respond to.
TArray<TObjectPtr<const UComboInputAsset>> FallbackInputs;
this->FallbackActions.GetKeys(FallbackInputs);
for (const TObjectPtr<const UComboInputAsset> &FallbackInput : FallbackInputs)
{
this->FoundInputsCache.Add(FallbackInput);
}
// Finally check the offset action for the final input to respond to.
if (this->OffsetMap.ComboInput)
{
this->FoundInputsCache.Add(this->OffsetMap.ComboInput);
}
}
return this->FoundInputsCache;
}
void UComboManagerComponent::FindAllUsedInputs_RecurseGraph(const UComboActionGraphNode *CurrentNode, TSet<const UComboInputAsset *> &FoundInputs)
{
for (const UComboActionGraphNode *NextNode : CurrentNode->ChildrenNodes)
{
// It should be safe to assume all of our nodes are action nodes. If at some point
// this becomes less reliable, this should be changed. But just for the sake of
// saving a bit of performance on start-up, we're doing this right now.
checkf(NextNode->GetClass() == UComboActionGraphNode_ActionNode::StaticClass(), TEXT("This graph contains non-action nodes. The cast in this function will fail."));
FoundInputs.Add(static_cast<const UComboActionGraphNode_ActionNode *>(NextNode)->GetComboInput());
this->FindAllUsedInputs_RecurseGraph(NextNode, FoundInputs);
}
}
const UComboActionGraphNode *UComboManagerComponent::FindActiveNodeData(const UComboActionGraphNode *CurrentNode, const UComboInputAsset *Input, const EComboActionTriggerEvent TriggerEvent, const UComboAction *&ComboAction) const UComboActionGraphNode *UComboManagerComponent::FindActiveNodeData(const UComboActionGraphNode *CurrentNode, const UComboInputAsset *Input, const EComboActionTriggerEvent TriggerEvent, const UComboAction *&ComboAction)
{ {
checkf(CurrentNode, TEXT("Attempting to find an active node from a null node.")); checkf(CurrentNode, TEXT("Attempting to find an active node from a null node."));

View File

@ -28,14 +28,15 @@ void UInputBufferComponent::InitializeComponent()
// Get the player character and try to connect to its combo manager. // Get the player character and try to connect to its combo manager.
this->OnNewComboInput.BindUObject(ComboManager, &UComboManagerComponent::HandleComboInput); this->OnNewComboInput.BindUObject(ComboManager, &UComboManagerComponent::HandleComboInput);
const TSet<const UComboInputAsset *> &ComboInputs = ComboManager->FindAllUsedInputs();
// Get all unique EnhancedInput actions bound to combo input actions. // Get all unique EnhancedInput actions bound to combo input actions.
const UInputBufferGlobalSettings *Settings = GetDefault<UInputBufferGlobalSettings>();
TSet<const UInputAction *> InputActionsToBind; TSet<const UInputAction *> InputActionsToBind;
for (TSoftObjectPtr<const UComboInputAsset> ComboInput : Settings->ComboInputs) for (const UComboInputAsset *ComboInput : ComboInputs)
{ {
if (ComboInput.IsValid()) if (ComboInput)
{ {
this->ComboInputList.Emplace(ComboInput.Get()); this->ComboInputList.Emplace(ComboInput);
for (const UInputAction *InputAction : ComboInput->ActionGroup) for (const UInputAction *InputAction : ComboInput->ActionGroup)
{ {
InputActionsToBind.Add(InputAction); InputActionsToBind.Add(InputAction);
@ -43,7 +44,7 @@ void UInputBufferComponent::InitializeComponent()
} }
else else
{ {
UE_LOG(LogInputBufferComponent, Verbose, TEXT("Invalid combo action found in Combo Actions list in %s"), *Settings->GetClass()->GetName()); UE_LOG(LogInputBufferComponent, Verbose, TEXT("Invalid combo input found"));
} }
} }
for (const UInputAction *InputAction : InputActionsToBind) for (const UInputAction *InputAction : InputActionsToBind)

View File

@ -58,6 +58,9 @@ public:
this->ComboActionEventBindings.Emplace(Key.Key, MoveTemp(Delegate)); this->ComboActionEventBindings.Emplace(Key.Key, MoveTemp(Delegate));
} }
// Recursively search the graph for all inputs used by the graph.
TSet<const UComboInputAsset *> &FindAllUsedInputs();
protected: protected:
UPROPERTY(BlueprintReadOnly, EditDefaultsOnly) UPROPERTY(BlueprintReadOnly, EditDefaultsOnly)
TObjectPtr<const class UComboActionGraph> ComboGraph; TObjectPtr<const class UComboActionGraph> ComboGraph;
@ -89,6 +92,7 @@ private:
void ResetCombo(); void ResetCombo();
const UComboActionGraphNode *FindActiveNodeData(const UComboActionGraphNode *CurrentNode, const UComboInputAsset *Input, const EComboActionTriggerEvent TriggerEvent, const UComboAction *&ComboAction); const UComboActionGraphNode *FindActiveNodeData(const UComboActionGraphNode *CurrentNode, const UComboInputAsset *Input, const EComboActionTriggerEvent TriggerEvent, const UComboAction *&ComboAction);
void FindAllUsedInputs_RecurseGraph(const UComboActionGraphNode *CurrentNode, TSet<const UComboInputAsset *> &FoundInputs);
void BroadcastDelegates(const class UComboAction *ComboAction, const EComboActionTriggerEvent &TriggerEvent); void BroadcastDelegates(const class UComboAction *ComboAction, const EComboActionTriggerEvent &TriggerEvent);
@ -103,6 +107,9 @@ private:
TObjectPtr<class UInputBufferComponent> AttachedInputBuffer; TObjectPtr<class UInputBufferComponent> AttachedInputBuffer;
// Cache of combo inputs found in the current graph.
TSet<const UComboInputAsset *> FoundInputsCache;
FTimerHandle FinishTransitionTimer; FTimerHandle FinishTransitionTimer;
FTimerHandle DEBUG__ResetComboTimer; FTimerHandle DEBUG__ResetComboTimer;

View File

@ -16,12 +16,6 @@ class COMBOINPUT_API UInputBufferGlobalSettings : public UDeveloperSettingsBacke
GENERATED_BODY() GENERATED_BODY()
public: public:
// List of possible combo inputs that can be taken. A combo input is selected from this list
// either if an action is made while the current combo is inactive, or when the previous
// action expires.
UPROPERTY(Config, BlueprintReadOnly, EditDefaultsOnly)
TSet<TSoftObjectPtr<const class UComboInputAsset>> ComboInputs;
// Length of time after releasing an input to keep the associated combo action buffered before clearing it. // Length of time after releasing an input to keep the associated combo action buffered before clearing it.
UPROPERTY(Config, BlueprintReadOnly, EditDefaultsOnly, meta=(UIMin="0.0", UIMax="0.5", ClampMin="0.0", ClampMax="0.5")) UPROPERTY(Config, BlueprintReadOnly, EditDefaultsOnly, meta=(UIMin="0.0", UIMax="0.5", ClampMin="0.0", ClampMax="0.5"))
float InputReleaseExpirationTimerLength = 0.15f; float InputReleaseExpirationTimerLength = 0.15f;