After programming my first AI approach for the traffic system I've noticed that the reasons for the decisions of the vehicle are a little bit difficult to observe.
But for the future game I expect far more complex decision systems. So I needed a better debuggable solution than coding in normal C# methods. After researching some hours I thought that “finite state machines” (FSM) could be a possible approach.
If found some implementations of FSM for Unity3D which were inspiring but not exactly what I needed:
- https://github.com/thefuntastic/Unity3d-Finite-State-Machine
- http://mitohnehaare.de/2011/05/11/zustandsautomaten-finite-state-machine-fsm/
- http://www.reddit.com/r/Unity3D/comments/2f6esc/c_need_help_understanding_a_finite_state_machine/
- https://github.com/thefuntastic/Unity3d-Finite-State-Machine
So I decided to write my own finite state machine. It looks like this:
My FSM works by creating an instance of a state object for every available stTransitions from this state to the next state are attached to the state.
For example: The vehicle should follow another vehicle when touching it´s back bumper bar. In this case the vehicle is running in the state “stateDrivingOnOthersBackBumperBar”. As soon as no more touching the back bumper bar the state should be exited and the state “DrivingForward” should be entered. So a transition “transitionNoMoreBackColliderTouched” has to be attached to the state.
In code this looks like this:
// Create a new state for driving on others vehicle bumper bar var stateDrivingOnOthersBackBumperBar = new StateDrivingOnOthersBackBumperBar(this); // Define the reason to activate to transition to change to state "DrivingForward" FsmTransition.IsFulfilled noMorebackColliderHit = () => !this.MyPhysics.GetColliders<VehicleBackCollider>().Any(); // Define "back-collider-ended-touching" transition var transitionNoMoreBackColliderTouched = new FsmTransition(noMorebackColliderHit, MyFsmStates.DrivingForward) { Order = 1, Name = "no more touching others back-bumper-bar", }; // add Is-no-more-touching-back-collider transition stateDrivingOnOthersBackBumperBar.AddTransition(transitionNoMoreBackColliderTouched);
Ok, now it works in a different way than before. But it still cannot be better observed. So the next thing I needed was a visual representation of what the finite state machine is “thinking”.
I wrote a Unity3D editor window to display this via a force-directed graph drawing: