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.
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.
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)