Add delegate for when state machine transitions to new state

This commit is contained in:
Kevin Poretti 2023-10-22 15:30:11 -04:00
parent 755ee34343
commit 28963c78e9
3 changed files with 30 additions and 2 deletions

View File

@ -16,6 +16,13 @@ void UFFInputBufferComponent::AddInput(const FFFInputState& InputState)
bool UFFInputBufferComponent::CheckInputSequence(const FFFInputSequence& InputSequence) bool UFFInputBufferComponent::CheckInputSequence(const FFFInputSequence& InputSequence)
{ {
if(InputSequence.Sequence.IsEmpty())
{
UE_LOG(LogTemp, Error,
TEXT("FFInputBufferComponent :: CheckInputSequence - tried to check input sequence but it was empty"));
return false;
}
int CondIdx = InputSequence.Sequence.Num() - 1; int CondIdx = InputSequence.Sequence.Num() - 1;
int ElapsedFrames = 0; int ElapsedFrames = 0;
for(int InpIdx = InputBuffer.Num() - 1; InpIdx > 1; InpIdx--) for(int InpIdx = InputBuffer.Num() - 1; InpIdx > 1; InpIdx--)

View File

@ -115,12 +115,14 @@ void UFFStateMachineComponent::GoToState(UFFState* NewState)
} }
} }
CurrentState->Exit(GetCurrentStateContext()); CurrentState->Exit(GetCurrentStateContext());
CurrentState = NewState;
TicksInState = 0; TicksInState = 0;
TickStateWasEntered = GetWorld()->GetGameState<AFFGameState>()->GetCurrentTick(); TickStateWasEntered = GetWorld()->GetGameState<AFFGameState>()->GetCurrentTick();
CurrentSubStateLabel = NAME_None; CurrentSubStateLabel = NAME_None;
CurrentState->Enter(GetCurrentStateContext()); NewState->Enter(GetCurrentStateContext());
OnStateTransition.Broadcast(CurrentState, NewState);
CurrentState = NewState;
} }
void UFFStateMachineComponent::GoToEntryState() void UFFStateMachineComponent::GoToEntryState()
@ -251,6 +253,11 @@ void UFFStateMachineComponent::TickComponent(float DeltaTime, ELevelTick TickTyp
SMDebugString.Append(FString::Printf(TEXT("Current State: %s\n"), *CurrentState->Name.ToString())); SMDebugString.Append(FString::Printf(TEXT("Current State: %s\n"), *CurrentState->Name.ToString()));
SMDebugString.Append(FString::Printf(TEXT("Current SubState Label: %s\n"), *CurrentSubStateLabel.ToString())); SMDebugString.Append(FString::Printf(TEXT("Current SubState Label: %s\n"), *CurrentSubStateLabel.ToString()));
SMDebugString.Append(FString::Printf(TEXT("Ticks In State: %lld\n"), TicksInState)); SMDebugString.Append(FString::Printf(TEXT("Ticks In State: %lld\n"), TicksInState));
SMDebugString.Append(FString::Printf(TEXT("-- States added --\n")));
for (auto TempState : States)
{
SMDebugString.Append(FString::Printf(TEXT("%s\n"), *TempState->Name.ToString()));
}
GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Green, SMDebugString); GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Green, SMDebugString);
} }

View File

@ -12,6 +12,9 @@
#include "FFStateMachineComponent.generated.h" #include "FFStateMachineComponent.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnStateTransitionSignature,
const UFFState*, PrevState, const UFFState*, NextState);
/** /**
* A state machine is a component that evaluates and controls the transitions for state objects that * A state machine is a component that evaluates and controls the transitions for state objects that
* are a part of this state machine. * are a part of this state machine.
@ -48,6 +51,9 @@ public:
* *
* @return A pointer to the state that was added or nullptr if there was an issue adding or creating the state * @return A pointer to the state that was added or nullptr if there was an issue adding or creating the state
*/ */
// TODO: return should probably be a const pointer if this function is public. I don't want
// anything outside of the state machine modifying the state. Really, I want states in general to
// be read only objects that are only modified at edit time when creating state blueprints.
UFFState* AddState(TSubclassOf<UFFState> StateClassToAdd); UFFState* AddState(TSubclassOf<UFFState> StateClassToAdd);
/** /**
@ -92,12 +98,18 @@ public:
UFUNCTION(BlueprintPure) UFUNCTION(BlueprintPure)
FORCEINLINE int64 GetTickStateWasEntered() const { return TickStateWasEntered; } FORCEINLINE int64 GetTickStateWasEntered() const { return TickStateWasEntered; }
UFUNCTION(BlueprintPure)
const UFFState* GetCurrentState() const { return const_cast<UFFState*>(CurrentState); }
/** /**
* Returns the name of the current state * Returns the name of the current state
*/ */
UFUNCTION(BlueprintPure) UFUNCTION(BlueprintPure)
FORCEINLINE FName GetCurrentStateName() const; FORCEINLINE FName GetCurrentStateName() const;
/**
* Returns the name of the current sub state label
*/
UFUNCTION(BlueprintPure) UFUNCTION(BlueprintPure)
FORCEINLINE FName GetCurrentSubStateLabel() const { return CurrentSubStateLabel; } FORCEINLINE FName GetCurrentSubStateLabel() const { return CurrentSubStateLabel; }
@ -115,6 +127,8 @@ public:
virtual void MovementModeChanged(EMovementMode PrevMovementMode, uint8 PreviousCustomMode, virtual void MovementModeChanged(EMovementMode PrevMovementMode, uint8 PreviousCustomMode,
EMovementMode NewMovementMode, uint8 NewCustomMode); EMovementMode NewMovementMode, uint8 NewCustomMode);
FOnStateTransitionSignature OnStateTransition;
// IFFSystemInterface interface // IFFSystemInterface interface
virtual void FixedTick(float OneFrame) override; virtual void FixedTick(float OneFrame) override;
// End of IFFSystemInterface interface // End of IFFSystemInterface interface