unity FSM

Having benefitted from useful enhancements like SpriteManager and GUIManager, I thought I’d offer something to help out the unity community.

It is a sharable-action finite state machine library; FSMs can really help organize your game logic if you need more than a simple switch statement.

Attach the TestRunner to a GameObject in your scene to run the tests. For usage, just check out the test cases.

Have fun!

171440–6170–$unity_fsm_892.zip (27.8 KB)

Thanks, I’ll check this out when I have time. For the benefit of those who aren’t clear on the benefits, maybe you could drop a reply with a few lines describing situations where this would be useful.

Sure,

It is essentially an object framework for modeling behavior. It can help to unify logic that is often spread across the code-base. So, instead of using if/else and switch statements to model state and behavior, you build a finite state machine diagram that contains States and Transitions.

Once you have your behavior modeled in a diagram by connecting States and Transitions, you can add Actions which actually implement the behavior. The Action system allows for nested Actions and can be shared in a pool to reduce memory and allocation overhead when you have many simultaneous FSMs running.

States have enter/step/exit actions and Transitions have condition/action actions.

By attaching and detaching Actions at runtime, you can customize the behavior while maintaining one FSM as a behavior “blueprint” (for instance, you could use the same FSM to model enemy AI and just assign different actions for each AI type). Since FSMs refer to contexts and hold no mutable data, they can be shared as well. So, build one FSM, and use it for all of your AI instances. Since Contexts contain your mutable data, persisting your logic is greatly simplified. Just persist the data from the context that is relevant; there is no need to save the FSM itself.

So, that’s basically it. Design your logic, build your diagram, then assign actions and conditions that implement your concrete behaviors.

If you find yourself with a lot of fine-grained actions, build some composites to consolidate and keep things organized. There is also a simple test framework that can be used for your unit testing, which helps immensely when trying to track down errors in logic.

As far as where this can be useful? The sky is really the limit, but to name a few:

Game Modes / Rules
Screen Navigation
AI Behavior
Input Modes (using actions as concrete input Strategies)

Look forward to trying it out. Sounds like it could cut out a lot of code sprawl.

Hi,
I downloaded and ran the test cases. Works fine but how can I integrate with the game?

I mean the test cases get started in Start() method but wouldn’t one need FSM to be running at all times when the game is running?

In the current setup wouldn’t the FSM just run to completion right away?

Thanks.

+1 for a javascript version 8)

AC

diagram.Step (context);

will progress your logic on the specific context, so you could call that from a central FixedUpdate on your active contexts, or a GameObject could call it from Update in one of its components on its own context. It is really left up to the developer to decide where and how frequently to update the logic.

If I find the time, I could make an exercise out of that to get up to speed with java script, but if anyone else out there wants to take a crack at it, by all means do!

If this library becomes widely used, I will invest some time into docs/tutorials, but for now the test cases and this thread are the only support line. Let me know what the demand is.

Thanks, 1r0nM0nkey.

I know your code is solid. Just by reading I know it is. I think I’m using it though not in a right way. I’ll try your advice and see how it works.

Thanks again.

Cool, non standard, idea, 1r0nM0nkey!

Very useful for in-game AI coding, imagine - you make a game, where gamer may make AI macros classes for they character or some NPC.

Thanks! Yes, you can do many cool things when you model actions as objects, especially at run-time. When work lets up, maybe I will build an editor/visual debugger for the framework as well. I think that would make things more accessible and could spark some interesting ideas like you mentioned.

Has anyone considering a UnityGUI-based view/editor for Unity FSM diagrams? I’m about to start on one.

it looks simple and pretty easy to use, but,… does it support nested states?

Depending on your needs, this is a fairly easy extension.

If you want a simple “push_state/pop_state” to override the current state, then derive a class OrthogonalState from State which implements the push/pop interface and provides a stack to manage the current state. This works well if you want to extend the functionality of the FSM library to support typical menu navigation. The “top:” state’s Step method’ (minimally) simply “hides” the lower states’.

If you want sub state diagrams within states, with entry and exit conditions, deep and shallow histories, rules for when to continue or abort sub-state processes, etc., then this would be a much more involved task.

What functionality are you looking for, specifically?

This looks incredibly useful. But that’s alot of code to digest. It would really help if you had a real scene with just one gameobject running around. with just a couple of states.

There are only just a few relevant classes and the rest are test cases, where you can see the usage. If you just dive in, you will probably find it less to digest than you think. In any case, here is a super-quick FSM extracted from a test:

//---------------------------

// Declarations...

Diagram diagram;
State open;
State closed;
Transition openToClosed;
Transition closedToOpen;
Transition startToClosed;
SimpleContext context;


// Construction...

open = new State ("open");
closed = new State ("closed");

openToClosed = new Transition (closed);
closedToOpen = new Transition (open);
startToClosed = new Transition (closed);

open.AddTransition (openToClosed);
closed.AddTransition (closedToOpen);

closedToOpen.SetCondition (new IsUnlocked ());

diagram = new Diagram ();
diagram.AddState (open);
diagram.AddState (closed);
diagram.GetStartState ().AddTransition (startToClosed);


// Create a Context instance... (as many as you like)

context = new SimpleContext (diagram.GetStartState ());

//---------------------------

// Lock/Unlock door based on events; this would be unique to your context
context.isLocked = false;

//---------------------------

// Step the logic (in Update, FixedUpdate, or wherever)
diagram.Step (context);  

//---------------------------

Incidentally, this mini-library has nothing to do with GameObjects directly, unless you choose to use the component Update methods to tick your logic.

Also it is important to note:

The advantage of this implementation is that the LOGIC is separate from the CONTEXT. So, you design your logic once (i.e. enemy AI behavior) and instantiate as many contexts as you like (each individual enemy). Saving complex game state is also made easier by being able to save the contexts, independent of their logic.

And, if you want to get wild and crazy, you could mix and match contexts and logic, although you would have to be disciplined enough to maintain compatibility or handle exceptions for odd cases. This means you could update logic without touching the contexts in future versions, and vice versa. This could take the form of in-app purchased upgrades, etc.

Additionally, the ACTIONS are only loosely coupled, allowing them to be shared and offering a high level of modularity. Actions are also of a composite nature allowing you to create hierarchical, functional action sets (which can be cached in an ActionPool) that can be plugged or unplugged at runtime and also don’t need to be serialized to get your gamestate back after a load. It is quite simple to implement a Strategy Pattern with the Actions, which can be very useful for things like dynamically swapping out input handing Actions on game mode switches.

States and Transitions can trigger various actions (enter, exit, conditions, etc.) although as a rule-of-thumb, it is a good idea to attach your Actions to transitions. Many game developers trigger logic while IN a particular state (which ‘can’ be ok) but a truly event-driven system reacts to changes in the Context. If nothing changed, nothing happens. I usually prefer a cyclic transition that reacts to an event over continuously updating logic while never leaving a state. If you do choose to update logic while in a state over many steps, you should ensure that this logic can gracefully recover from being interrupted if a transition happens to be triggered.

Hope that gets your foot in the door…

I don’t know of one for FSMs as such, but AngryAnt’s Behave tool has an editor for behaviour trees, which have roughly the same purpose as FSMs.

Hi,

This looks extremely useful, but the lack of a test project and the fact that it is very abstract make it hard to dive in. There are example classes, but I have no idea what they are supposed to be doing, and how they relate to eachother.

What’s the TestRunner class supposed to do? Apprantly, it makes TestCases. But what does the TestCase class do? I can probably figure it out after a while, but because it’s so vague, I can’t see it at first glance.

What makes it worse is that for some reason you don’t indent the statements within a function. For me, and I suspect others, this makes it extremely hard to read. (You’re the first person I ever saw coding like this. I’m interested to know if there’s a reason.)

Don’t get me wrong, I want to use this, and I appreciate you sharing this, and it looks like you have a very useful tool here, but it’s not very accessible. And I consider myself at least an intermediate programmer, so other people with less experience will find it even harder.

Well, I’m gonna try to figure it out anyway, but I do hope you can knock up a good example on how to use this in a real life situation. For instance, a sphere that’s moveable by the user, and a cube that starts following the sphere once it gets too close (no pathfinding, just moving towards), and that occasionaly shoots - or something like that.

Hi Smag, I too like the idea of using this FSM class and I am also trying to understand how to use the code.

When trying to learn something new, I find it helpful to run things through a single step debugger (it’s a feature I’d dearly like to see in Unity or the ability to use MonoDevelop for that purpose). To that end I made a few minor changes to allow the TestRunner class to run standalone under Visual C# 2008.

I can post the project here if theres any interest in that.

To 1r0nM0nkey or anyone else already up to speed with these FSM classes who be interested in working on a tutorial, the 3DBuzz website has a nice (free) video tutorial series on how to make a simple 2D shooter. It would be cool to see something like that updated to use this set of classes. Another idea might be to use it for controlling Menu GUI states in conjunction with the GUIManager2 class.

iByte

Just wondering if anyone else is using this FSM package. There was some talk earlier on in the thread about “editor/visual debugger for the framework”.

Ir0nM0nkey did you ever have the cycles to work on that project?

iByte

Hi iByte
I’d like to give the Visual C# 2008 project a go-- if you can post it. Perhaps it will help me to understand the FSM code.

Thx
lnickers@austin.rr.com