- Release triggers only fire if one is available in the current node's children.
- Crashes related to PreviousNode occasionally becoming null have been fixed.
This commit is contained in:
parent
08b89b9d84
commit
b77a9bd2ed
@ -28,18 +28,19 @@ void UComboManagerComponent::InitializeComponent()
|
||||
Super::InitializeComponent();
|
||||
|
||||
checkf(this->ComboGraph, TEXT("No combo graph is set for %s in actor %s"), *UComboManagerComponent::StaticClass()->GetName(), *this->GetOwner()->GetName());
|
||||
this->ActiveNode = this->ComboGraph->StartNode;
|
||||
this->PreviousNode = this->ActiveNode = this->ComboGraph->StartNode;
|
||||
}
|
||||
|
||||
void UComboManagerComponent::SetComboGraph(const UComboActionGraph *Graph)
|
||||
{
|
||||
checkf(Graph, TEXT("Attempting to set a null combo graph."));
|
||||
|
||||
this->ComboGraph = Graph;
|
||||
|
||||
this->FoundInputsCache.Empty();
|
||||
this->FindAllUsedInputs();
|
||||
|
||||
this->ActiveNode = this->ComboGraph->StartNode;
|
||||
this->PreviousNode = nullptr;
|
||||
this->ResetCombo();
|
||||
}
|
||||
|
||||
|
||||
@ -123,11 +124,40 @@ void UComboManagerComponent::DEBUG__UnlockAction(TObjectPtr<const UComboInputAss
|
||||
|
||||
void UComboManagerComponent::ReleaseComboAction(const class UComboInputAsset *Input)
|
||||
{
|
||||
if (this->LastComboAction)
|
||||
if (this->LastComboAction && this->ActiveNode)
|
||||
{
|
||||
this->BroadcastDelegates(this->LastComboAction, EComboActionTriggerEvent::Released);
|
||||
this->LastComboAction = nullptr;
|
||||
// See if we have a fallback we can release.
|
||||
const TObjectPtr<const UComboAction> *FallbackAction = this->FallbackActions.Find(Input);
|
||||
if (FallbackAction && *FallbackAction == this->LastComboAction)
|
||||
{
|
||||
this->ResetCombo();
|
||||
this->BroadcastDelegates(*FallbackAction, EComboActionTriggerEvent::Released);
|
||||
UE_LOG(LogComboManagerComponent, Verbose, TEXT("Fallback action %s released"), *(*FallbackAction)->ActionName.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find a node that matches the release action.
|
||||
const UComboAction *ComboAction = nullptr;
|
||||
for (const UComboActionGraphNode *Node : this->ActiveNode->ChildNodes)
|
||||
{
|
||||
if (const UComboActionGraphNode_ActionNode *ActionNode = StaticCast<const UComboActionGraphNode_ActionNode *>(Node))
|
||||
{
|
||||
if (ActionNode->GetTriggerEvent() == EComboActionTriggerEvent::Released)
|
||||
{
|
||||
ComboAction = ActionNode->GetComboAction();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ComboAction)
|
||||
{
|
||||
this->BroadcastDelegates(ComboAction, EComboActionTriggerEvent::Released);
|
||||
UE_LOG(LogComboManagerComponent, Verbose, TEXT("%s released"), *ComboAction->ActionName.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->LastComboAction = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -148,8 +178,16 @@ void UComboManagerComponent::FinishTransition()
|
||||
void UComboManagerComponent::ResetCombo()
|
||||
{
|
||||
this->GetWorld()->GetTimerManager().ClearTimer(this->DEBUG__ResetComboTimer);
|
||||
this->PreviousNode = this->ActiveNode;
|
||||
this->ActiveNode = this->ComboGraph->StartNode;
|
||||
this->PreviousNode = this->ActiveNode = this->ComboGraph->StartNode;
|
||||
|
||||
APlayerController *Controller = UGameplayStatics::GetPlayerController(this, 0);
|
||||
if (UInputBufferComponent *InputComponent = Cast<UInputBufferComponent>(Controller->InputComponent))
|
||||
{
|
||||
for (const UComboInputAsset *Unlock : this->FoundInputsCache)
|
||||
{
|
||||
InputComponent->UnlockComboInput(Unlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -179,13 +217,13 @@ TSet<const UComboInputAsset *> &UComboManagerComponent::FindAllUsedInputs()
|
||||
}
|
||||
void UComboManagerComponent::FindAllUsedInputs_RecurseGraph(const UComboActionGraphNode *CurrentNode, TSet<const UComboInputAsset *> &FoundInputs)
|
||||
{
|
||||
for (const UComboActionGraphNode *NextNode : CurrentNode->ChildrenNodes)
|
||||
for (const UComboActionGraphNode *NextNode : CurrentNode->ChildNodes)
|
||||
{
|
||||
// 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());
|
||||
FoundInputs.Add(StaticCast<const UComboActionGraphNode_ActionNode *>(NextNode)->GetComboInput());
|
||||
this->FindAllUsedInputs_RecurseGraph(NextNode, FoundInputs);
|
||||
}
|
||||
}
|
||||
@ -196,7 +234,7 @@ const UComboActionGraphNode *UComboManagerComponent::FindActiveNodeData(const UC
|
||||
|
||||
// Find a node that matches both the combo input and the trigger action.
|
||||
const UComboActionGraphNode *NextNode = nullptr;
|
||||
for (const UComboActionGraphNode *GraphNode : CurrentNode->ChildrenNodes)
|
||||
for (const UComboActionGraphNode *GraphNode : CurrentNode->ChildNodes)
|
||||
{
|
||||
if (const UComboActionGraphNode_ActionNode *ActionNode = Cast<UComboActionGraphNode_ActionNode>(GraphNode))
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user