Modding Tutorials/Animation Explained

Intro
3D animation is a complex undertaking. This is doubly true when using the tools available to you as an Arma 3 modder. (This page is focused on vehicle animation. It applies somewhat to buildings and mostly not-at-all to humans/creatures.)


 * This is a very long page with some redundant pieces of information. This is intentional---you may end up returning frequently to focus on different sections depending on where you are in the animation process.
 * Most sections are collapsed to keep the page from being overwhelming. However, if you want to run a word search or use table-of-contents links, you must expand the sections.

Glossary
Expand and read this section if you are new to vehicle animation in Arma 3. The Arma 3 skeleton and animation system uses a welter of confusingly generic or similar-sounding names that mean completely different things. e.g. "named selection", "selection", "section". Read carefully and don't mix them up!
 * named selection: Any geometry (including vertices) in a P3D file may be grouped as desired in sets called "named selections". If you want parts of your model to be animated, the geometry must be in a named selection that has the same name as the corresponding bone from the CfgSkeletons class.
 * bone: Bones have animations applied to them, causing a model's parts to move. Bone names are created in the CfgSkeletons class ("skeletonBones[]" property). But without corresponding elements in a model's P3D file, they are pretty useless:
 * Visual/shadow/fire geometry must be in named selections with the same name as the bone. This attaches the geometry to the bone so that it moves with the bone as it animates.
 * If the bone moves or rotates, an axis consisting of two vertices must be placed in the Memory LOD as well--the name here should not be the same as the bone, as the axis name is referenced by it's own property ("Axis") in the Animation class. This tells the bone its location and orientation in the model. (Bones for hide animations don't need representation in the Memory LOD, the geometry naming step above is all that's needed).


 * skeleton: A hierarchy of bones for a single vehicle. The list of bones in "skeletonBones[]" defines links between bones one connection at a time in the form "child","parent". (i.e. a 3-bone chain of "bone1">"bone2">"bone3" would be defined as "bone2","bone1" on one line and "bone3","bone2" on the next line). Bones which have 'no parent' are actually attached to the root of the vehicle in the form "bone","". e.g.


 * selection: A property in the Animations class (model.cfg>CfgModels). It tells you which bone in skeletonBones[] is moved by the animation.


 * axis: An axis is defined by a pair of verts in the Memory LOD of a P3D file. It determines both the location and the orientation of a bone--these being necessary for animation purposes. (The first vert placed in an axis determines the 'forward' direction for translation animations? )


 * source: A property of both the CfgModels>Animation class and the (optional) CfgVehicles>AnimationSources class. It identifies which input property drives the animation--as the input's value changes, the bone animates.
 * This is usually one of the many generic preset sources provided by the engine . But any source which is not in that list requires a supplementary listing in the AnimationSources class of CfgVehicles . These could be custom user scripts, but more commonly they are a set of undocumented presets that link to some specific named selection in the vehicle (rather than a generic name used across vehicles). For example, a common 'custom' source in CfgVehicles is a hit location hide animation, which uses the source = "Hit";.
 * Note that multiple animations can use the same source to do different things.


 * section: Sections are not part of the bone-based animation process, but they do appear in CfgModels. A "section" is a discrete portion of geometry designed to have its texture swapped in-game via the hiddenSelections[] property or the Damage class--both found in CfgVehicles. Creating a section requires three steps:
 * 1) The geometry in a section must be in a single Named Selection in the P3D file (across all visual LOD's)
 * 2) The same name must be included in model.cfg>CfgModels>sections[]
 * 3) This step depends on which texture-swapping feature is being used:
 * If the section is being used as a hiddenSelection, the name must be used in config.cpp>CfgVehicles>hiddenSelections[].
 * If the section is being used for a Damage-class texture swap, the name must be used in the visual property of the relevant HitPoint class.
 * Note: apparently, every additional section in the scene slows down the rendering process a bit, so don't add them if you don't need them.

Components Used

 * Bones: Defined in model.cfg>CfgSkeletons>...>skeletonBones[]. This is where bones are named and (optionally) hierarchically linked. Animations are applied to bones, therefore a bone must exist in order for you to animate part of your vehicle.


 * Animation in CfgModels: Defined in model.cfg>CfgModels>Animations class. All properties of a standard animation can be defined here.


 * Named Selections: This is how a bone knows what pieces of geometry move with it. The named selections are assigned to geometry in a vehicle's P3D file. The named selection must have the same name as the bone which it will move with. You can and should use the same name across all LOD's that will be animated by the bone (visual, fire geometry, shadow, etc.).


 * Axis: This is how the bone knows where it is located and the axis it moves/rotates on. These are defined in the Memory LOD of the P3D file. An axis consists of two verts in a Named Selection. The name should be unique--e.g. in the form "axis_boneName"--not the same name as a bone. (Note: certain types of animation--like "hide"--do not require an axis to be defined; if this is the only type of animation you are using on the bone, don't bother creating an axis).


 * Animation in CfgVehicles: This component is not required for all types of animation, but you will find it is necessary for many of them. The AnimationSources class in CfgVehicles is used to define custom "sources"--i.e. any source which is not in the list of generic vehicle presets. Custom sources include things like UserAction scripts . But they occur more frequently in the form of (undocumented) vehicle-specific templates: associating recoil with a particular weapon name, hiding individual hit locations when they are destroyed (as opposed to hiding parts of the model only when the whole vehicle is destroyed), animating crew hatches opening and closing, and others. If there is an overlap, animation settings in AnimationSources override those in CfgModels.

model.cfg

 * The model skeleton (a hierarchy of bones) is defined here: bones names are listed and any links between bones are created. An animation requires a bone to operate on.
 * All base animations are defined here (although some types require further elaboration in config.cpp).

P3D

 * Geometry is attached to bones (via identical naming) here: any geometry in a Named Selection that is the same as a bone name will move with that bone as it animates; this works across multiple LODs (visual, fire geometry, etc.).
 * Bone position and orientation are defined here via axes in the Memory LOD. Remember, axes should be uniquely named--not bone-named; the animations in model.cfg let you identify which axis is used for an animation. Axes are necessary for movement/translation bones; hide bones can be defined by the step above only.

config.cpp

 * Certain animation types (e.g. destroyable hit locations) require an additional animation definition in the CfgVehicles>AnimationSources class (over and above the base on in model.cfg).

(sqf)

 * As an alternative to the built-in approach involving the above file types, an animation can be run directly from a script via the animate command: see in  below.

Creating an Animation
Expand for the basic steps required to build an animation.

1. Skeleton Definition

 * Obviously this step is only done once for the vehicle as a whole, not for each animation.
 * The skeleton is defined in the vehicles's model.cfg & P3D files as summarized in above.
 * An animation needs a bone to operate on, therefore you must a bone for each animation.

2. Create Base Animation

 * Under model.cfg>CfgModels>...>Animations, create a class named for the animation and fill in the standard properties.
 * Some of the properties used vary by animation type, but they are pretty well documented here: . (Several source names are not documented, some become obvious when you see examples of them in one of the stock Arma 3 model.cfg files, e.g. "gmeterX", etc.)

3. Supplement Animation
'Standard' animations do not require this step. But some animation types must be supplemented with a corresponding part in config.cpp>AnimationSources:
 * If the animation contains a vehicle-specific source, pattern your usage by finding a relevant AnimationSources template (either documented in this wiki or by studying BI files).
 * Any animation that is based on a UserActions script also needs to appear in this class.

Script-driven Alternative

 * Animations can also be driven directly by a script via the animate command.
 * The typical property settings required for such an animation are as follows:
 * The source must be a custom one (i.e. defined in CfgVehicles>AnimationSources). You cannot use "user" or "direct" as a source in the CfgModels>Animation class itself.
 * The source in CfgVehicles should be "user" (for a timed animation) or "direct" (for an instant one).
 * e.g.


 * The animate command tells Arma "animate up to this point in the phase and then stop"; the time it takes to get to that point is based on the animPeriod.
 * e.g. if we have an animation called "thing_hide" with an animPeriod of 1.5, _vehicle animate ["thing_hide", 0.5] will take 0.75 seconds to get the animation to phase 0.5 and stop there.
 * For "direct" and animPeriod=0 animations, the animation is instant.

Animation Properties
Expand for descriptions of the various animation class properties and their values.

Clarifying Terms
Let's use a few terms for clarity in the descriptions below:
 * source (animation): The "source" property--as the value of this property changes, it drives your animation's "phase". Note that any number of animations can be driven by the same source.
 * target (animation): The animation you're defining--it is driven by the source animation.
 * phase: This is just a number that tells you how far along you are in an animation. While most sources have a phase of 0 to 1, some are different (-1 to 1, for example). Typically, you will want to match the target phase with the source phase by having minValue & maxValue be the same as the source start and end phase values.

CfgModels

 * source: (string) The source value phase drives your target animation phase. As the source goes from its min phase to its max phase, your target animation does the same--going from minValue to maxValue.
 * Expand for long list of values (these are known ones, there are more; some of these are typically used in AnimationSources rather than CfgModels)


 * aileron: The main aileron control surfaces. (Airplane)
 * aileronB: The bottom speed brake as opening ailerons. (Airplane)
 * aileronT: The top speed brake as opening ailerons. (Airplane)
 * altBaro: The baro altitude. (Aircraft).
 * altRadar: The radar altitude. (Aircraft).
 * aoa: The Angle Of Attack. (Aircraft).
 * BackDamper: The suspension of the back wheels of the vehicle.	Car?
 * clockHour: The current time in hours.
 * clockMinute: The current time in minutes. Derived from clockHour.
 * clockSecond: The current time in seconds. Moves discreetly every second and independently from clockHour.
 * compassArrow: The arrow.	Compass
 * compassCover: The cover.	Compass
 * compassPointer: The pointer.	Compass
 * damage: Current damage level (0-1: 0=healthy, 1=destroyed)
 * damper: The suspension of the vehicle. Currently only works with type translationY.
 * direct: Like "user", but transitions instantly to the phase specificed in the animate command (animPeriod is treated as 0--and you cannot use animPeriod = 0 with a "user" source).
 * NOTE/BUG: a "direct"source acts like a global toggle--all source = "direct" animations will trigger as soon as any one of them triggers.
 * direction: The orientation of the vehicle.
 * door: A custom script driven source intended for doors. It is animated with the somewhat more powerful |animateDoor command instead of |animate. Like any custom source, it can only be used in AnimationSources. It is also apparently limited in that the base animation in CfgModels must have type = rotation. (So you cannot use it as a catch-all to give any base animation type the power of animateDoor--at least it doesn't appear to work with base type = hide, although it may also work with base type = translation).
 * drivingWheel: The orientation of the steering wheel. Used for the steering wheel and steered wheels.
 * elevator: The elevators. (Airplane).
 * flag: Runs from 0 to 1 as flag is taken from flagpole. (Flagcarrier).
 * flap: The flaps. (Airplane).
 * FrontDamper: The suspension of the front wheels of the vehicle.
 * fuel: The fuel level.
 * gear: The vehicle's gear. (Aircraft).
 * gmeter: The G-forces.
 * gmeterX: The G-forces.
 * gmeterY: The G-forces.
 * gmeterZ: The G-forces.
 * hasOptics: Whether a scope is attached to the weapon (used not so much as an animation but a boolean toggle to know when to flip up iron sights in the absence of a scope ,). (Weapon).
 * *hatchCommander: The commander hatch.
 * hatchDriver: The driver hatch.
 * *hatchGunner: The gunner hatch.
 * horizonBank: The banking angle of the vehicle. (Aircraft).
 * horizonDive: The diving angle of the vehicle. (Aircraft).
 * *mainGun: The main gun.	Car, Tank, Helicopter, Ship
 * *mainTurret: The main turret.	Car, Tank, Helicopter, Ship
 * noseWheelTurn: (Airplane).
 * *obsGun: The observer or commander gun.
 * *obsTurret: The observer or commander turret.
 * oil: IndicatorOilTemp	?
 * pedals: The pedals. (Bicycle).
 * reload: The movement when reloading(??).
 * revolving: returns the number of bullets left in whatever magazine the specified weapon is using.
 * must be followed by the line: weapon = "WEAPON_NAME";
 * rotor: The rotors. (Airplane).
 * rotorH: The 'horizontal' rotor. (Helicopter).
 * rotorV: The 'vertical' rotor. (Helicopter).
 * rotorHDive: Tilt of the 'horizontal' rotor. (Helicopter).
 * rotorVDive: Tilt of the 'vertical' rotor. (Helicopter).
 * rpm: The rpm of the vehicle. Used in rpm indicators.
 * rudder: The rudder. (Airplane).
 * scudLauncher: Phase of scudlaunch. (Scud).
 * speedBrake: The speed brake. (Airplane).
 * speed: The speed of the vehicle. Used in speed indicators. (WARNING: 'maxValue' and 'minValue' should be in meters per second)
 * support: The support stand. (Motorcycle).
 * time: Timer-based input.
 * turretDir: The orientation of the turret.
 * user: User defined (script driven) animation. Can only be used in AnimationSources. Use this source when you will be using a script to drive the animation.
 * vertSpeed: The vertical speed. (Aircraft).
 * wheel: Normal wheels that turn based on moving forward.	Car, Airplane, Motorcycle
 * wheelL: The left track wheels. (TankX).
 * wheelR: The right track wheels. (TankX).
 * zeroing1: Number of range settings for muzzle #1 (primary?) of this weapon (zero-based). . (Weapon).
 * zeroing2: Number of range settings for muzzle #2 (secondary?) of this weapon (zero-based). . (Weapon).


 * minValue: (float) The minimum phase for your target animation. Typical value is 0.
 * maxValue: (float) The maximum phase for your target animation (at which point it stops, loops, or mirrors depending on your sourceAddress value). Typical value is 1.
 * hideValue: (float) This number tells you at what point in the target phase the model hides itself. (-1 disables hide).
 * unHideValue: (float) This number tells you at what point in the target phase the model shows itself. (-1 disables unHide).
 * initPhase: (float) The starting phase of your animation. For the typical 0-1 phase, this is essentially always 0. (It can be set to values other than minValue if useful).
 * sourceAddress: (string) What your animation does if your phase is ever beyond minValue or maxValue:
 * clamp = anim stays locked at maxValue
 * loop = anim starts up again at the minValue and runs forward again
 * mirror = anim runs backward to minValue and then runs forward (i.e. the animation 'ping-pongs' back and forth).

AnimationSources
Below are some examples of the kinds of 'templates' that can be found in the AnimationSources class of BI's config files.

'hitpoint animations'
In 'hitpoint animations', the source that drives your animation is the local damage state of a particular hit location. It is the equivalent of using the generic preset source "damage"--except that "damage" refers to the global damage state of the whole vehicle, while this custom source refers to the damage state of the desired hit location only. Damage states are expressed as a continuous float value ranging from 0 (no damage) to 1 (100% damage--the vehicle or location is destroyed). Thus your source phase is the usual 0-1.
 * source: (string) This value is always "Hit"; so we can assume this is an undocumented preset source type specifically for hitpoint-damage-driven animations.
 * hitpoint: (string) This is simply the name of the HitPoint class whose damage state should be driving your target animation.
 * raw: (boolean) This value always appears to be 1 (true) in hitpoint animations. It appears to have something to do with giving the hit location damage value in the desired format (a continuous float value ranging from 0 [no damage] to 1 [100% damage]).

Example Animations
These are some common animation templates used in Arma 3 configs. They are useful references when creating your own animation of a similar type.

A. Standard
These animations can be handled using model.cfg only.

Hiding geometry when the vehicle is destroyed

 * CfgModels


 * AnimationSources

Turning wheels

 * CfgModels


 * AnimationSources

Indicator dial on a control panel

 * CfgModels


 * AnimationSources

B. Custom Sources
These animations require use of both model.cfg and config.cpp.

Weapon recoil

 * CfgModels
 * AnimationSources

Open/close hatch animation

 * CfgModels


 * AnimationSources

Destructible hit location (e.g. glass window)

 * (See separate page)

Destructible hit location with swapping (e.g. tire)

 * (See separate page)

Muzzleflash show/hide

 * CfgModels
 * AnimationSources

Random muzzle flash rotation

 * CfgModels
 * AnimationSources

Hide model parts based on ammo remaining

 * CfgModels


 * AnimationSources

C. Custom Scripted
These animations involve scripted commands and require work in model.cfg>CfgModels, config.cpp>AnimationSources and config.cpp>UserActions.

Vehicle door open/close

 * CfgModels


 * AnimationSources

Links
,,,,,