if ((Player getVariable "SpareTime") > 0) then {...
« Changelog 08/11/2009New to ArmA 2: FSM - Scripted FSM by xeno »

New to ArmA 2: FSM - A sample

Permalink 11/05/09 22:53, by jonas, Categories: ArmA

Let's create the civilian script we've talked before.
The civilian should stand idle until the player starts aiming at him, then he will raise his hands and surrender. But only as long as the player aims.

We basically need 2 states: One where he idles, one where he surrenders. The final FSM will have some more, but more on this later.


doFSM will set three local variables within our FSM: _units, _destination and _target
We will only use _target to identify the unit running the FSM.

For creating our FSM, we'll use BIS FSM Editor.

Beginning from the start state we will create a new condition, set it to a true condition (via context menu), then connect the condition to a new state. This will be our idle state.

Next step is to check if the player is aiming at our victim.
So we create a new condition 'Pointed at' in which we are checking if


cursorTarget == _target

When this condition is true, we'll enter the 'Raise hands' state where the civilian will raise it's hands:


_target globalChat "Don't fire!";
_target playAction "Surrender";
_target disableAI "ANIM";

Next step is to check if the player stopped pointing at him. So a new condition 'Not pointed anymore' with


cursorTarget != _target

That's it. That's the basic FSM.

That's not all :no:

True, the civilian won't lower his hands since we disallowed him to switch animations :oops:
So we need to modify our 'idle' state:


_target enableAI "ANIM";
_target playAction "Stand";

We allow him to switch animations and bring him to switch to the Stand animation.

That's still not all!

That's all for the basic. The civilian will raise his hands as soon as we aim at him and will lower then when we stop aiming.
But it doesn't look good. He will lower his hands as soon as move away even for a second. And our FSM doesn't have an end state.

Let's correct this:
'Not pointed anymore' is not connect with 'Idle', instead we use a new state: 'Sleep'


_time = time;

Then we connect 'Sleep' with 'Idle' via the condition 'Check sleep':


_time + 1 < time

'Check sleep' will become true a second after our FSM entered the 'Sleep' state. So we get a delay of one second till the civilian will lower his hands.

And: Those two statements show us something special about FSM: Local variables are valid within the hole FSM. _time set in 'Sleep' is the same as in 'Check sleep'. We don't have to use global variables here.

But what happens if I aim again at him within this second?

He'll lower his hands even if you point at him again. So we connect 'Sleep' with 'Pointed at'.
'Sleep' now has two outgoing conditions. ArmA will check both and move in the according state.

But what happens if both are true?

One of them will be checked before the other. So the first true condition will win. Luckily we can modify the order by setting a priority: The higher priority will get checked first.
So let's set 'Pointed at' to priority 1.

It's nearly done &amp;#58;&amp;#41;

We just need to add an end state. We connect every state (aside of 'Start') via the following condition with 'End':


not alive _target

Then we raise the priority of those condition to the highest since we don't need to do anything if the civilian is already death.

The state 'Swear' is just a small gimmick:
If there are bullets flying around him while he has his hands raised, he'll will 'complain' about it.

And it works &amp;#59;&amp;#68;
The civilians don't move, but since you know the basics, it should be easy to enhance the FSM!



Comment from: kju [Visitor]
kjuIf you try to view the pictures in full size, the file cannot be found. :(
11/06/09 @ 10:40
Comment from: jonas [Member] Email
jonasFixed the links
11/06/09 @ 18:50
Comment from: zonker [Visitor]
zonkerThese are very helpful and informative articles. I have a much better understanding of how and when an FSM might come in handy. Thank you!
08/19/10 @ 16:32