IsFollowupState flag and replace FollowupState with GetFollowupState

This commit is contained in:
Kevin Poretti 2024-01-31 21:59:28 -05:00
parent 50a3bd8a4b
commit b8ffa48b47
4 changed files with 38 additions and 18 deletions

View File

@ -57,7 +57,7 @@ bool UFFState::CanTransition(const FFFStateContext& InStateContext)
return false;
}
return OnCanTransition(InStateContext);
return OnCanTransition(InStateContext) && !bIsFollowupState;
}
@ -163,26 +163,24 @@ void UFFState::Finish(const FFFStateContext& InStateContext, EFFStateFinishReaso
// the appropriate flags are set. I think having this state finish reason is good but I may want
// to rethink the way we handle logic for ending a state and which class is in charge of handling
// what
if(FollowupState != NAME_None)
if(GetFollowupState() != NAME_None)
{
InStateContext.Parent->GoToState(FollowupState, StateFinishReason);
InStateContext.Parent->GoToState(GetFollowupState(), StateFinishReason);
}
else
{
InStateContext.Parent->GoToEntryState(StateFinishReason);
}
}
void UFFState::RegisterInputHandler(const FFFInputSequence& InRequiredSequence, FFFInputEventDelegate InDelegate)
FName UFFState::GetFollowupState_Implementation()
{
FFFInputEventHandler TempHandler;
TempHandler.RequiredSequence = InRequiredSequence;
TempHandler.Delegate = InDelegate;
InputHandlers.Add(TempHandler);
return FollowupState;
}
void UFFState::PlayMontage(const FFFStateContext& InStateContext)
{
// TODO: think of a better way to handle optionally playing montages other than the one set as MontageToPlay

View File

@ -126,6 +126,17 @@ public:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="UFF State Properties")
bool bCanTransitionToSelf = false;
/**
* Specifies whether a state is a followup state or not.
*
* Followup states are states that should only be transitioned into from another specific state
* but otherwise have no other specific conditions that need to be met to transition.
* Setting this flag to true when there are no other conditions prevents this state from
* constantly being transitioned into by the state machine.
*/
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="UFF State Properties")
bool bIsFollowupState = false;
/**
* State to transition to when this state is finished. If left blank then the entry state
* of the state machine will be transitioned into.
@ -197,10 +208,12 @@ public:
EMovementMode NewMovementMode, uint8 NewCustomMode, const FFFStateContext& InStateContext);
// TODO: document
// TODO: call this callback when the avatar is hit
// TODO: pass in hitdata struct as well
virtual void Hit(const FFFStateContext& InStateContext);
// TODO: document
// TODO: call this callback when the avatar blocks a hit
// TODO: pass in hitdata struct as well
virtual void Block(const FFFStateContext& InStateContext);
@ -219,12 +232,7 @@ public:
*/
UFUNCTION(BlueprintCallable)
virtual void Finish(const FFFStateContext& InStateContext, EFFStateFinishReason StateFinishReason);
// TODO: document
UFUNCTION(BlueprintCallable)
virtual void RegisterInputHandler(
const FFFInputSequence& InRequiredSequence, FFFInputEventDelegate InDelegate);
// TODO: document
UFUNCTION(BlueprintNativeEvent, Category="UFF|State|Events")
void OnInit(const FFFStateContext& InStateContext);
@ -255,16 +263,30 @@ public:
UFUNCTION(BlueprintImplementableEvent, Category="UFF|State|Events")
void OnUpdate(float OneFrame, const FFFStateContext& InStateContext);
/**
* Returns the next state to transition into when this state finishes.
*
* This is called during the Finish function, either when the state duration is reached or the
* state is manually finished due to some other logic.
*
* By default this returns the name of the state specified by the FollowupState property or
* NAME_None if the FollowupState is not specified.
*/
UFUNCTION(BlueprintNativeEvent, Category="UFF|State|Events")
FName GetFollowupState();
// TODO: Don't like this at all and needs to be refactored or redesigned
UFUNCTION(BlueprintCallable, Category="UFF|State|Animations")
void PlayMontage(const FFFStateContext& InStateContext);
// TODO: Don't like this at all and needs to be refactored or redesigned
/**
* Blueprint hook for overriding the logic for when a anim montage plays at the start of a state
* @param InStateContext
*/
UFUNCTION(BlueprintNativeEvent, Category="UFF|State|Events")
void OnPlayMontage(const FFFStateContext& InStateContext);
// TODO: document
UFUNCTION(BlueprintImplementableEvent, Category="UFF|State|Events")
void OnLanded(const FHitResult& Hit, const FFFStateContext& InStateContext);

View File

@ -224,7 +224,7 @@ UFFState* UFFStateMachineComponent::FindStateWithName(FName StateName)
}
}
UE_LOG(LogTemp, Warning,
UE_LOG(LogTemp, Error,
TEXT("Could not find state in state machine with name %s"), *StateName.ToString());
return nullptr;

View File

@ -184,7 +184,7 @@ protected:
UPROPERTY()
UFFState* CurrentState;
/** Current SubState label or NAME_None if there is no SubState label set for the current state*/
/** Current SubState label or NAME_None if there is no SubState label set for the current state */
FName CurrentSubStateLabel;
// TODO: should be a TMap