Finite State Machine For Weapons

Making an Unreal Engine game solo is quite introspecting experience in a way. Not only you can take independent decisions but also you have to take the responsibility of those decisions and ability to convince others (while presenting the work). Thus there is an element of democracy in the process and if done right, could be a secularist process, in the sense that you constantly get to challenge the dogma. Then this process becomes necessary for proper evolution of everything involved in making of games.

For instance Epic’s global illumination way of making photorealistic graphics (Lumen) can be reasonably questioned and some, if not many, studios have chosen to do without getting into the complexity which is not measured by checking a particular field in the details panel.

For my game with the theme of shooting and killing zombies, I decided to use FSM for different states of weapon for instance firing and just holding. A very apt article on FSM for games is in game programming patterns. A well known game Unreal Tournament also uses FSM for weapons. So I took some code from there and used that in my game.

"These (FSMs) came out of a branch of computer science called automata theory whose family of data structures also includes the famous Turing machine"

A minor glimpse of the design can be seen here. The FSM states that I consider are

  1. USTWeaponStateFiring – When the weapon is firing
  2. USTWeaponStateActive – When weapon is not firing but being held by player
  3. USTWeaponStateInActive – When weapon is not held by player (dropped weapon etc)
  4. Zooming – When player is using zoom feature

They are all derived from a single base class USTWeaponState defined like so

UCLASS(DefaultToInstanced, EditInlineNew, CustomConstructor, Within=STWeapon)
class SUNOVATECHZOMBIEKILL_API USTWeaponState : public UObject
{
    ...
}

The variable for caching the current state is declared like so


/**
 * @brief The present state of the weapon. Basically cache for weapon's  
 * finite state machine
 * 
 * @note UT uses UUTWeaponState
 */
UPROPERTY(BlueprintReadOnly, Category = "Weapon")
USTWeaponState* CurrentState;

Finally, the code for transitioning of weapon’s state is like so

/**
 * @brief FSM's routine for state transition
 * 
 * @param NewState The weapon state to transition to
 */
virtual void GotoState(class USTWeaponState* NewState);

All the possible FSM states are instantiated and initialized in the constructor like so

ActiveState = ObjectInitializer.CreateDefaultSubobject<USTWeaponStateActive>(this,
TEXT("StateActive"));
for (int32 i = 0; i < 2; i++)
{ 
USTWeaponStateFiring* NewState = ObjectInitializer.CreateDefaultSubobject<USTWeaponStateFiring, USTWeaponStateFiring>(this, FName(*FString::Printf(TEXT("FiringState%i"), i)), false);
}