void FPawnActionStack::PopAction(UPawnAction& ActionToPop)
{
    // first check if it's there
    UPawnAction* CutPoint = TopAction;
    while (CutPoint != NULL && CutPoint != &ActionToPop)
    {
        CutPoint = CutPoint->ParentAction;
    }

    if (CutPoint == &ActionToPop)
    {
        UPawnAction* ActionBeingRemoved = TopAction;
        // note StopAction can be null
        UPawnAction* StopAction = ActionToPop.ParentAction;

        while (ActionBeingRemoved != StopAction)
        {
            UPawnAction* NextAction = ActionBeingRemoved->ParentAction;

            if (ActionBeingRemoved->IsBeingAborted() == false && ActionBeingRemoved->IsFinished() == false)
            {
                // forcing abort to make sure it happens instantly. We don't have time for delayed finish here.
                ActionBeingRemoved->Abort(EAIForceParam::Force);
            }
            ActionBeingRemoved->OnPopped();
            if (ActionBeingRemoved->ParentAction)
            {
                ActionBeingRemoved->ParentAction->OnChildFinished(*ActionBeingRemoved, ActionBeingRemoved->FinishResult);
            }
            ActionBeingRemoved = NextAction;
        }

        TopAction = StopAction;
    }
}
EPawnActionAbortState::Type UPawnActionsComponent::AbortAction(UPawnAction& ActionToAbort)
{
    const EPawnActionAbortState::Type AbortState = ActionToAbort.Abort(EAIForceParam::DoNotForce);
    if (AbortState == EPawnActionAbortState::NeverStarted)
    {
        // this is a special case. It's possible someone tried to abort an action that
        // has just requested to be pushes and the push event has not been processed yet.
        // in such a case we'll look through the awaiting action events and remove a push event
        // for given ActionToAbort
        RemoveEventsForAction(ActionToAbort);
    }
    return AbortState;
}
void UPawnActionsComponent::OnUnregister()
{
    if ((ControlledPawn != nullptr) && !ControlledPawn->IsPendingKillPending())
    {
        // call for every regular priority
        for (int32 PriorityIndex = 0; PriorityIndex < EAIRequestPriority::MAX; ++PriorityIndex)
        {
            UPawnAction* Action = ActionStacks[PriorityIndex].GetTop();
            while (Action)
            {
                Action->Abort(EAIForceParam::Force);
                Action = Action->ParentAction;
            }
        }
    }

    Super::OnUnregister();
}
EPawnActionAbortState::Type UPawnActionsComponent::ForceAbortAction(UPawnAction& ActionToAbort)
{
    return ActionToAbort.Abort(EAIForceParam::Force);
}