« Changelog 08/11/2009 | New to ArmA 2: FSM - Scripted FSM by xeno » |
New to ArmA 2: FSM - A sample
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
Code:
cursorTarget == _target |
When this condition is true, we'll enter the 'Raise hands' state where the civilian will raise it's hands:
Code:
_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
Code:
cursorTarget != _target |
That's it. That's the basic FSM.
That's not all
True, the civilian won't lower his hands since we disallowed him to switch animations
So we need to modify our 'idle' state:
Code:
_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'
Code:
_time = time; |
Then we connect 'Sleep' with 'Idle' via the condition 'Check sleep':
Code:
_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
We just need to add an end state. We connect every state (aside of 'Start') via the following condition with 'End':
Code:
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
The civilians don't move, but since you know the basics, it should be easy to enhance the FSM!
3 comments


