Warning: Intense programming ahead

Reasoning

I recently ran into a problem with my state machines: their behaviors were distributed to multiple classes or multiple “Update” or “Enter” methods.  This is okay when each state has truly unique behaviors, but many of my state machines had reoccurring actions throughout my states.  A centralized location and structure for behaviors of states is what I wanted, I wanted to troubleshoot “attached behaviors” and “behavior execution” separately and efficiently.  This meant grouping “attached behaviors” and handling “behavior execution” in one spot.  The latter is pretty common, but the former is not.

I recently experimented with using enum-attributes to remedy this.  It’s likely not the most efficient, but it made for some clean and short code.  This isn’t the most efficient state machine I’ve written, but it is the most interesting one that I’ve actually utilized.

When I plan on using this:

  • State machine with reoccurring actions between states
    • e.g. regenerating health
  • State machine with reoccurring values needed for each state
    • e.g. Which Menu the “Back” button goes to in menu system
    • When you wish your Enums were classes

The Enum

Above we have a series of Enumerators (Standard, Submerged , Skip, …) and Attributes attached to each of them (Regen_HP, Regen_Stall, Set_Actual).

The Attribute

They’re an extension of C#’s Attribute class.  While an Interface or Abstract base class would be ideal for a more elaborate system, this will do for now.

How do we utilize these attributes?

Luckily we’re 21st century programmers with Google, so StackOverflow does most the work for us.  The first example is an extension of the Enum class that we need, whereas the latter is the utilization of said extension.

This should be inside a static extensions class.

This should go inside an Update or FixedUpdate loop (programmer's choice).

.GetState() is a method I’ve implemented to return the plane’s current State (it returns type “States”).

An Implementation

Summary

While was a pretty hasty implementation, I’ve found it very useful.

Pros

  • Centralize common state-behaviors
  • Reduced boilerplate code
  • Readable behaviors (which states do what)
  • Can be latched onto existing state machine
  • Doesn’t use reflection

Cons

  • Less performant
    • Not cached
  • Poorly typed
  • Epic Rare implementation

I know I haven’t explained much, but hey, I have a game to make.  If you have any questions or comments, feel free to drop a line into the comments or fire me a mention on Twitter.

 

Edit: Some small changes made to reflect some feedback.  To the Pros/Cons and the sample-code.