Best way to create a Finite State Machine on blueprints?

Hello! Fairly new Unreal user here. Im creating a player characters, and I have doubts about how to structure it. I always use the Finite State Machine pattern, which comes handy when limiting player actions. However, I cannot find any resources about how to emulate this pattern in Unreal blueprints. All tutorials I see just drop the logic and use some bools to prevent player actions when not desired, but this obviously works only if your player has two or three states. I would like to aim to a more generic and scalable solution.
The basic idea of a FSM is “I have this chunk of code running > some variable has changed > I deactivate the first chunk and activate the second chunk”, but being UE an event-based engine, I ran into the problem of “how can I deactivate chunks of blueprints and unbind all bound events, but in a generic manner, so I don’t have to manually rebind all input each state”.
I thought of using Blueprint functions like “Entering Run State” or “Entering Idle State”, so I can transition between states just by calling the function. But, how I should handle event binding if, for example, I want to deactivate player input if character is falling?
I don’t know everything unreal can offer me, so maybe I’m having the incorrect approach to this pattern.
PS: please, refrain from linking plugins, the idea is to learn base unreal and handling difficult tasks by myself.

People often use anim logic graphs

Yeah, that’s handy, but as I know, this tool is mainly to handle animations. I was talking to replicate this behaviour, but for the logic side. As far as I know, this doesn’t work to, for example, changing input.

I think you just have to code it up yourself.

I have done it for certain objects etc.

I basically used a switch node to change states. The state was just a string.

I know that, I have created FSM before, but my main question is how to handle Events (specially input events) to prevent undesired behavior to work at a certain state. If Unreal was a query-based engine, it would be easy to use a switch to choose between different Tick functions, but being event-based, it becomes trickier

Well, you just don’t call the stuff that’s not relevant, basically.

Typically I have a function to check whether an action can be done given current states.

For example, Fire input/event → Can I Fire (function) return: bool → Branch → (true) → fire action → set state

In the conditional function I’ll check if:

  • Is equipped (actually has a weapon equipped)
  • Current weapon obj is valid
  • ammo > 0
  • not falling
  • not in swimming state
  • and many other bools/states etc.

It can be a tedious process, but it has to be done. I always start out by determining “what should prevent this action from occurring”. I set up all the needed conditional vars. Then write my If statements.

Take a look at the Character Movement Component (CMC) Jump and Crouch/UnCrouch functions.

https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp

example: Jump line 877

bool UCharacterMovementComponent::DoJump(bool bReplayingMoves)
{
	if ( CharacterOwner && CharacterOwner->CanJump() )
	{
		// Don't jump if we can't move up/down.
		if (!bConstrainToPlane || FMath::Abs(PlaneConstraintNormal.Z) != 1.f)
		{
			Velocity.Z = FMath::Max(Velocity.Z, JumpZVelocity);
			SetMovementMode(MOVE_Falling);
			return true;
		}
	}
	
	return false;
}

bool UCharacterMovementComponent::CanAttemptJump() const
{
	return IsJumpAllowed() &&
		   !bWantsToCrouch &&
		   (IsMovingOnGround() || IsFalling()); // Falling included for double-jump and non-zero jump hold time, but validated by character.
}

UnCrouch starts on line 2703

void UCharacterMovementComponent::UnCrouch(bool bClientSimulation)
1 Like