// Unreal Fighting Engine by Kevin Poretti #include "FEStateMachineComponent.h" // FE includes #include "FEState.h" UFEStateMachineComponent::UFEStateMachineComponent() { // Don't use Unreal's tick instead use a fixed tick PrimaryComponentTick.bCanEverTick = false; } void UFEStateMachineComponent::Initialize() { for(const TSubclassOf& CurrState : DefaultStates) { UFEState* TempState = AddState(CurrState); if(!CurrentState) // first state to be created is the entry into this state machine { CurrentState = TempState; CurrentState->Enter(); } } } void UFEStateMachineComponent::InitActorInfo(AActor* InOwner, AActor* InAvatar) { Owner = InOwner; Avatar = InAvatar; } UFEState* UFEStateMachineComponent::AddState(TSubclassOf StateClassToAdd) { UFEState* TempState = NewObject(this, StateClassToAdd); if(TempState) { States.Add(TempState); TempState->InitActorInfo(Owner, Avatar); return TempState; } return nullptr; } void UFEStateMachineComponent::AddStates(const TArray>& StateClassesToAdd) { for(const TSubclassOf& CurrState : StateClassesToAdd) { AddState(CurrState); } } void UFEStateMachineComponent::RemoveState(FName StateToRemove) { UE_LOG(LogTemp, Error, TEXT("UFEStateMachineComponent::RemoveState is not yet implemented")); } void UFEStateMachineComponent::SwitchStates(UFEState* NewState) { check(NewState); CurrentState->Exit(); CurrentState = NewState; CurrentState->Enter(); } FName UFEStateMachineComponent::GetCurrentStateName() const { return CurrentState ? CurrentState->Name : NAME_None; } UFEState* UFEStateMachineComponent::FindStateWithName(FName StateName) { for (UFEState* CurrState : States) { if(CurrState ->Name == StateName) { return CurrState; } } UE_LOG(LogTemp, Warning, TEXT("Could not find state in state machine with name %s on %s"), *StateName.ToString(), *Owner->GetName()); return nullptr; } void UFEStateMachineComponent::BeginPlay() { Super::BeginPlay(); Initialize(); } void UFEStateMachineComponent::FixedTick(float OneFrame) { // Should we switch states? for(UFEState* CurrState : States) { // Check if the state is enabled // Check state entry conditions if there are any // Check input conditions if there are any // If all state entry conditions are good and at least one input condition is good then we can transition // Lastly just check if the state we're about to transition into isn't the current state. // It is OK to transition if state's "CanTransitionToSelf" is true // SwitchStates(NewState); // return; } // CurrentState should never be null // TODO: Should probably assert or whatever UE's equivalent is check(CurrentState); // Tick current state CurrentState->Update(OneFrame); // Debug }