[go: up one dir, main page]

Skip to content

UE5 Finite State Machine (FSM) mimicking the Unreal 3 FSM

Notifications You must be signed in to change notification settings

Tonetfal/UE5FSM

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

65 Commits
 
 
 
 
 
 
 
 

Repository files navigation

UE5FSM

This is a Finite State Machine (FSM) developed for Unreal Engine 5 that mimics behavior of Unreal Engine's 3 FSM. The tool is developed with a focus on gameplay logic to facilitate the development of complex behavior.

Installation

Download the release that you wish to use from the Release page, and copy its Plugins directory into your project's root.

The plugin is dependant on UE5Coro. Refer to its documentation for the installation process and other features.

Description

Finite State Machine is an actor component that is meant to be attached to actors that have a state. You can make different logic using that. Each piece of logic has to be built using machine states and their labels. The machine states have a wide range of events and functions to control the logic flow. The machine state always know what state it's in in order to start or abort context dependant logic. Every machine state can have its unique data object to store its own project-specific data in. There are tools to debug your own finite state machines easily. If those aren't enough, you can always extend them pretty easily by adding more debug information to it.

Read more the plugin in the documentation and in the source code, as it's all well documented.

Example

Take a look at how you can make a simple AI that can walk to a target and attack it.

using namespace UE5Coro;

UCLASS()
class AMyAIController : public AAIController
{
	GENERATED_BODY()

public:
	AMyAIController();

protected:
	//~AAIController Interface
	virtual void OnPossess(APawn* InPawn) override;
	//~End of AAIController Interface

protected:
	UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category="AI")
	TObjectPtr<UFiniteStateMachine> StateMachine = nullptr;
};

UCLASS()
class USeekingState : public UMachineState
{
	GENERATED_BODY()

protected:
	//~UMachineState Interface
	virtual TCoroutine<> Label_Default() override;
	//~End of UMachineState Interface

	AActor* GetTarget() const;
};

UCLASS()
class UAttackingState : public UMachineState
{
	GENERATED_BODY()

protected:
	//~UMachineState Interface
	virtual TCoroutine<> Label_Default() override;
	//~End of UMachineState Interface

	void StartAttacking();
	UAnimMontage* GetAttackAnimation();
};
AMyAIController::AMyAIController()
{
	StateMachine = CreateDefaultSubobject<UFiniteStateMachine>("FiniteStateMachine");
	StateMachine->bAutoActivate = false;

	// It's better to register them within blueprint properties; we're doing that here to show the shortest variant
	StateMachine->RegisterState(USeekingState::StaticClass());
	StateMachine->RegisterState(UAttackingState::StaticClass());
}

void AMyAIController::OnPossess(APawn* InPawn)
{
	Super::OnPossess(InPawn);

	// Activate it once the controller gets a pawn to make the FSM to run logic upon it
	StateMachine->Activate(true);
}

TCoroutine<> USeekingState::Label_Default()
{
	// Walk to a target
	RUN_LATENT_EXECUTION(AI::AIMoveTo, GetOwner<AAIController>(), GetTarget());
	
	// Upon reaching the target push the attacking state to harm it
	PUSH_STATE(UAttackingState);
	
	// Repeat the function
	GOTO_LABEL(Default);
}

AActor* USeekingState::GetTarget() const
{
	// Somehow get a target...
}

TCoroutine<> UAttackingState::Label_Default()
{
	StartAttacking();

	// Wait until the attack animation ends
	const auto* Character = GetOwner<AAIController>()->GetPawn<ACharacter>();
	const UAnimInstance* AnimInstance = Character->GetMesh()->GetAnimInstance();
	while (AnimInstance->Montage_IsPlaying(GetAttackAnimation()))
	{
		// Wait until the animation doesn't end
		RUN_LATENT_EXECUTION(Latent::NextTick);
	}

	// Finish attacking; this will return us to the last state, in this case to the seeking state
	POP_STATE();
}

void UAttackingState::StartAttacking()
{
	// Somehow start attacking...
}

UAnimMontage* UAttackingState::GetAttackAnimation()
{
	// Somehow get the animation...
}

About

UE5 Finite State Machine (FSM) mimicking the Unreal 3 FSM

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages