Phase 1 - standing aroundEdit
In this phase we will learn the how to translate an FSM graph to the blender logic bricks. As example we let GUS stay around with a little motion. That makes him look alive.
- Download the sample file.
- Lets get rid of the ball objects as we do not need them in phase 1.
- Shift select all ball objects and move them to a hidden layer (e.g. 3).
Now we have GUS without the ball objects ready to start with the tutorial. But first some theory.
Unfortunatly the Game engine does not tell us when an animation (action) ends. Therefore it is difficult to use the action actuator in play mode. A better way is the action actuator in property mode:
- Select GUSs armature.
- Add an int property named frame as int with default 1. This will be our frame counter.
The property frame will tell as which pose of the current animation is shown by GUS. By changing the frame the pose will be changed as well. In this example the animations start with 1 and are always played forward. Following logic let the property frame count upward. By setting frame to 0 frame the animation will not play.
- Add a property sensor sFrameNot0. Enable true pulse. The sensor triggers true if the property frame is not equal to 0.
- Add an AND controller name it cFrame.
- Connect sFrameNot0 with cFrame.
- Add a property actuator with the name aFrame++. Let it add 1 to the property frame.
- Connect cFrame to aFrame++
The Finite State Machine GraphEdit
I do not wan't to explain FSM in detail here. I recommend to read Finite state machine before procceding with the next section.
In difference to the article mentioned above I use an own notation. The actions are written next to the states/transitions they belong to. The prefix shows the type of action followed by the actuator type and parameters of the actuator.
My actuator types are:
|act||action||action name||It is a property action actuator. The property is "frame"|
|msg||message||message subject||send to all|
|-||property||property name||new value|
If required new types and parameters can be added.
Here is an example:
- st - a state action,
- act: performed by an action actuator,
- GUS_standing playing the action GUS_standing
The actions are usually actuators. I used following notation for actuators:
- act - blender action (animation) followed by the start frame
- msg - messages followed by it's subject
The events are usually sensors. I used following notation for sensors:
- "key" - the key "key" was pressed
- frame xx - the property frame contains the value xx
A first simple FSM graphEdit
The FSM starts with the state init. While GUS is in the state init he can perform various task for initialization. There is not really much to do in this stage. GUS will go on to the state stand.
The entry action for state stand is en-frame1. This means the property frame will be set to 1. This resets the current animation to the beginning.
The state action for state stand is to play the animation "GUS_standing".
When the property frame is 151 the animation "GUS_standing" ends. GUS performs a transition from state stand to state stand. This let GUS restart the animation.
The state is just a value within a property. It does not matter what value it is as long it is different to the values of other states. An easy solution is to store the states within a property called state. If it is a string property meaningful values can be choosen.
By the way the values of all properties of an object determine its state. The FSM will concentrate on the state property only.
- Select GUSs armature.
- Add a property state as string with the default value init (the start state).
The state initEdit
To determine the state of GUS we need sensors that check the property state. These sensors are not drawn in the FSM graph as they are implicit represented by the states itself. Each existing state need a sensor that checks for the state name. I named the sensors sState<State name>. For each state we need one sensor.
- Add a property sensor that checks the property state for the value init. Call the sensor sStateInit.
The state standEdit
- Add a property sensor that checks the property state for the value stand. Call the sensor sStateStand.
The transition between the states is represented by the arrow within the graph. The state where the arrow comes from is the current state. The state where the arrow points to is the next state. The event to trigger a transition is written next to the arrow.
A transition can be implemented by changing the property state from one value to another. This can even be the same value as before.
The logic bricks of a transition consists of a state sensor, one or more event sensors, a controller, and a actuator that changes the value of the property state.
I named the event sensors s<Event> to identify the event. The name of the transition controller is c<Current state>-><Next state>. This makes it easier to match the transition from the graph with the controller. The name of the actuator is aState<Next state>.
- Add an always sensor with the name sSceneStart. Switch the true pulse off.
- Add an AND controller. Name it cInit->Stand".
- Connect the sensor sStateInit with the controller cInit->Stand.
- Connect the sensor sSceneStart with the controller cInit->Stand.
- Add a property actuator that assigns the value "stand"' to the property state. Name it aStateStand.
- Connect the controller cInit->Stand with the actuator aStateStand.
- Switch on debug for the property state and enable Game>Show debug properties.
- Start the Game Engine and see the state switches to "stand".
Stand -> StandEdit
As the standing animation will come to an end (at frame 151) we need to restart the standing animation. This will be done by a transition from state stand to stand.
- Add a property sensor named sFrame151 that checks the property frame to be equal to 151.
- Add an AND controller named cStand->Stand.
- Connect the sensor sStateStand with the controller cStand->Stand.
- Connect the sensor sFrame151 with the controller cStand->Stand.
- Optional: Connect cStand->Stand with aStateStand.
Remark: The next sections require the logic bricks described in section "Playing animations".
Actions are represented by actuators. Also the state transition contains an action - the state change. This action is implicit and represented by the arrow. All other actions are explicit written down.
The type of action determines when the action is performed.
Entry actions are performed when a transition to the current state is finished regardless of the prior state.
I would just add a property change sensor. But this sensor will not fire if a transition back to the current state (stand->stand) is done. Therefore it is necessary to have a property that shows when a state changed. The property will be int that is not zero when the state changed.
To determine if the state was changed all transitions must add 1 to statechanged. There should be only one transition at the time. Each time statechanged is bigger then zero statechanged should be decreaced by 1. This ensures that also imediate transitions are detected.
- Add an int property statechanged with default 1.
- Add a sensor that checks the property statechanged not to be zero. Name it sStatechanged. Set true pulse to fire everytime when the property is not zero.
- Add an AND controller cNoStatechange.
- Connect the sensor sStatechanged with the controller cNoStatechange.
- Add an actuator that adds -1 to the property statechanged. Name it aStatechanged--.
- Connect cNoStatechange to aStatechanged--.
- Add an actuator that adds 1 to the property statechanged. Name it aStatechanged++.
- All transition controllers must be connected to aStatechange++ to tell us the state has changed. In this case there is only one - Connect controller cInit->Stand to actuator aStatechange++.
In our FSM graph the entry action for stand is frame1. This means the property frame should be set to 1. This let the current animation play frame 1.
- Add an AND controller cEn-Stand.
- Connect the sensor sStatechanged with the controller cEn-Stand
- Connect the sensor sStateStand with the controller cEn-Stand
- Add an property actuator that sets the property frame to 1. Name it aFrame1.
- Connect cEn-Stand with the actuator aFrame1
State actions are simple to build. They should be performed as long as the state remains the same. It is enough to check the value of the property state.
Here is how to add the state action "st-act:GUS_standing":
- Add an AND controller with the name cStand.
- Connect the sensor sStateStand with the controller cStand.
- Add an action actuator named aStanding. Select the action type "Property". Enter GUS_standing in the field "AC:" and frame in the field "Prop:".
- Connect the controller cStand with aStanding.
Finally the logic bricks should be sorted a little bit to provide a better overview. I placed logical blocks together: Animation logic, State change logic, Transition logic and Action logic.