Procedural Animation Editor Basics Tutorial – Arma Reforger
For the demonstration of how Procedural Animation Editor works, let's see the example of vehicle exhaust, the end of which should be shaking a bit when the engine of the vehicle is on.
This shake should be also affected by vehicle RPM and also be a bit bigger when engine goes on or off. Let's go into it.
Create Files
- Create a new .pap and .siga file:
- File > New > Project for the .pap file (or Ctrl + ⇧ Shift + N)
- File > New > Signal for the .siga file
Input and Output
- In the .siga file, create two new Inputs and name them EngineRPM and EngineOn. - these are this animation's two parameters. In the same file, create an Output and name it EngineShake (the naming here is up to the modder).
Project Setup
- In the .pap file, click on Signal
- In the new window, navigate to the existing .siga file and press OK
- Create two new nodes RotationMake and RotationSet
- Connect the Signal's EngineShake output to both X and Y axis inputs of the RotationMake node
- Connect RotationMake's Out to RotationSet's Rotation input
- In the view window, select the vehicle:
- Click on the SelectModel button
- Search for UAZ469_base.xob and select the .xob file
- Select on the model the bone to be used. Click on the exhaust bone (should be v_exhaust and select Add bone - this will create a Bone node
- Connect this new Bone node to RotationSet's In input
Signal Processing
Now that the .pap project file has been set up, it is time to work with the .siga file, in order to process the signal from the engine. The following picture represents the wanted end result and is described in the next steps.
The whole process can be divided into two branches:
Engine RPM
Let's handle the shaking of exhaust based on engine RPM:
- Create a Value node and set its value to 7500
- Create a Div node in order to divide engineRPM (value in range 0..~5000) by the Value's set value (7500)
- Connect the Input engineRPM's Out to Div's In input
- Connect the Value's Out to Div's Divisor input
- Create a Random node to generate a random value
- Set its min value to -0.6 and max value to 0.6 to make it generate a random number in -0.6..+0.6 range
- Create a Mul node to multiply the result of the division output by the random value
- Connect the Div's Out and the Random's Out to Mul's In
- Create a Smoother node
- Set its Fade-in and Fade-out values to 300 (milliseconds)
- Keep "Interpolate First" ticked
- Connect the Mul's Out to Smoother's In
- Connect the Smoother's Out to Output engineShake's In
The exhaust now shakes according to engine's RPM as well as a little randomization.
Engine On
Let's handle a shake of exhaust on start and stop of the engine:
- Create a Smoother node, keep its default values
- Connect the Input engineOn's Out to this Smooker's In
- Create a Convertorsic node
- Set this node's Intervals' values (min/max/out):
[0] 0.100/0.300/0.500
[1] 0.301/0.600/1.000
[2] 0.601/0.900/0.500
[3] 0.901/1.000/0.000
- Set this node's Intervals' values (min/max/out):
- Connect the Smoother's Out to the Convertorsic's In (not Default)
- Create another Smoother node
- Set its Fade-in value to 300 (milliseconds) and this time set its Fade-out value to 0
- Connect the Convertorsic's Out to the Smoother's In
- Create a Random node
- Create a Mul node to multiply Smoother's and Random's Out values
- Connect the Smoother's Out and the Random's Out to Mul's In
The whole Signal file is not completed! There are still "dangling" nodes.
Now, in order to merge (by sum) engineRPM and engineOn's results, we will change engineRPM's flow:
- Disconnect Output engineShake from the Smoother node
- Create a Sum node
- Connect the two open ends to it: the last Smoother node from engineRPM and the last Mul node from engineOn
- Connect the Sum's Out to engineShake
The final result should look like the following image.
Vehicle Setup
Now, the last thing to be done is to set up the vehicle. For that, a CarProcAnimComponent has to exist on the vehicle:
Hit the "+" button in its Parameters section and add a new ProcAnimParams. As a ResourceName navigate to the created .pap file, in BoneNames click on "+" button and select the bone to be animated.
Index of added bones on ProcAnimComponent has to be same as the order in .pap file.
Same goes for inputs in .siga file, or the following could happen:
3 new input boxes were created in .siga file in order Sig1, Sig3, Sig2. In script, using SignalManager's FindSignal method:
FindSignal | Expected index | Actual index |
---|---|---|
<enforce>int sigInd1 = m_SignalManager.FindSignal("Sig1");</syntaxhighlight> | 0 | 0 |
<enforce>int sigInd2 = m_SignalManager.FindSignal("Sig2");</syntaxhighlight> | 1 | 2 |
<enforce>int sigInd3 = m_SignalManager.FindSignal("Sig3");</syntaxhighlight> | 2 | 1 |