Particle Effects – Arma 3
Definition of effect
There are two ways how to define particle effect in Arma 3 - script and config. Pros and cons of config-defined effects:
|
|
Config
Each Complex Effect (CE) is created by Part-Effects (PE) (defined in CfgCloudlets) and light (defined in {{#Link|Arma 3: CfgLights|CfgLights}}).
Definition of complex effect
Class of CE is defined directly in configFile and consists of classes that link PE (or light) to the parent effect.
class ComplexEffect
{
class Example1
{
simulation = "particles"; // type of simulation - particles or light
type = "Default"; // name of PE's class defined in CfgCloudlets or light's class defined in CfgLights
position[] = { 0, 0, 0 }; // position related to the default position or memorypoint
lifeTime = 0.05; // life time of emitter
qualityLevel = -1; // effect is only used when the the particle quality option [[particlesQuality]] in user settings matches this qualityLevel.
// -1 play everytime, 0 play only on low, 1 play only on normal, 2 play only on high. Default: -1
start = 1; // is used only if the lifeTime parameter is defined, if value is changed from negative to positive then the effect is triggered
enabled = 1; // 1 effect is enabled, -1 effect is disabled
};
};
Definition of part-effect
Class of PE must be in configFile class CfgCloudlets.
#define true 1
#define false 0
class SomeClass
{
interval = "0.5 * speedSize + 0.5"; // interval of particle's creation
circleRadius = 0; // radius around emitter where particles are created
circleVelocity[] = { 0, 0, 0 }; // direction and speed of movement of particle's circle
particleShape = "\A3\data_f\ParticleEffects\Universal\Universal"; // path and name of file
particleFSNtieth = 16; // How many rows there are in the texture. For example Universal is 16x16, so particleFSNtieth is 16. Default: 1
particleFSIndex = 12; // Row index 0 based, so particleFSIndex 12 will mean 13th row from the top. Default: 0
particleFSFrameCount = 8; // How many frames from the start of the chosen row to animate (particleFSFrameCount 8 means animate frames 1,2,3,4,5,6 and 7 in sequence). Default: 1
particleFSLoop = 1; // Whether or not to repeat from the beginning when all frames got played (0 - false, 1 - true). If particleFSLoop is 0 animation sequence is played only once. Default: 1
animationSpeed[] = { 3, 2, 1 }; // interpolated speed of animation in animation cycles per second.
// e.g if particleFSFrameCount is 8 and animationSpeed at the time is 0.4 result in 8 * 0.5 = 4 frame changes per second.
// Value 1000 is a special value but only when combined with particleFSLoop 0;
// this will instruct the engine to play only the last frame of the given count, so if particleFSFrameCount is 5, animationSpeed[] is {1000} and particleFSLoop is 0 only 5th frame will be played.
angle = 0; // angle of particle
angleVar = 0; // variability in angle of particle
animationName = "";
particleType = "Billboard"; // type of animation (Billboard (2D), Spaceobject (3D))
timerPeriod = 1; // interval of timer (how often is called script defined in parameter onTimerScript)
lifeTime = 1; // life time of particle in seconds
moveVelocity[] = { 0, 0, 0 }; // direction and speed of movement of particle [x,z,y]
rotationVelocity = 0; // direction and speed of rotation of particle [x,z,y]
weight = 1; // weight of particle (kg)
volume = 1; // volume of particle (m3)
rubbing = 0.05; // how much is particle affected by wind/air resistance
size[] = { 1, 1 }; // size of particle during the life
color[] = { { 1, 1, 1, 1 }, { 1, 1, 1, 0 } }; // color of particle during the life (r,g,b,a)
randomDirectionPeriod = 0; // interval of random speed change
randomDirectionIntensity = 0; // intensity of random speed change
onTimerScript = ""; // script triggered by timer (in variable "this" is stored position of particle)
beforeDestroyScript = ""; // script triggered before destroying of particle (in variable "this" is stored position of particle)
lifeTimeVar = 0; // variability in lifetime of particle
position[] = { 0, 0, 0 }; // defines position of effect
positionVar[] = { 0, 0, 0 }; // variability in position of particle (each part of vector has it is own variability)
positionVarConst[] = { 0, 0, 0 }; // variability in position of particle (variablity of all parts of vector is the same)
moveVelocityVar[] = { 0, 0, 0 }; // variability in direction and speed of particle (each part of vector has it is own variability)
moveVelocityVarConst[] = { 0, 0, 0 }; // variability in direction and speed of particle (variablity of all parts of vector is the same)
rotationVelocityVar = 0; // variability in rotation of particle
sizeVar = 0; // variability in size of particle
colorVar[] = { 0, 0, 0, 0 }; // variability in color of particle
randomDirectionPeriodVar = 0; // variability in interval of random speed change
randomDirectionIntensityVar = 0; // variability in intensity of random speed change
sizeCoef = 1; // size of particle = size parameter value * this coef (works only in some effects)
colorCoef[] = { 1, 1, 1, 1 }; // color of particle = color parameter value * this coef (works only in some effects)
animationSpeedCoef = 1; // animation speed of particle = animationSpeed parameter value * this coef (works only in some effects)
destroyOnWaterSurface = 0; // particle can exist - only underwater (-1), only above the water (1), everywhere (0)
destroyOnWaterSurfaceOffset = 0; // offset of water surface in destroyOnWaterSurface parameter
destroyAfterCrossing = false; // if true, destroy when the whole particle is on the other side of the water surface. Only when _destroyOnWaterSurfaceOffset is enabled
onSurface = true; // placing of particle on (water) surface on start of it is existence, default value is true, works only if circleRadius > 0
keepOnSurface = false; // true for particle is stay on water surface - see notes below
surfaceOffset = 0; // offset of water surface in keepOnSurface parameter
bounceOnSurface = 0.6; // coef of speed's loosing in collision with ground, 0-1 for collisions, -1 disable collision
bounceOnSurfaceVar = 0.0; // variability in speed's loosing in collision with ground
postEffects = "IEDMineFlame"; // effect triggered before destroying of particle
particleEffects = "ExplosionShardsFire"; // emitter of effect defined in this parameter is attached to each particle
ignoreWind = false; // if true, wind will not be applied on the particle
blockAIVisibility = true; // sets if particles are in the AI visibility tests (default true) - false for better performance but AI is able to see through particles
emissiveColor[] = { { 30, 30, 30, 0}, { 0, 0, 0, 0 } }; // sets emissivity of particle, 4th number has no meaning for now
// --- fire damage related parameters (optional)
damageType = "Fire"; // damage type, only available option is "Fire" so far
coreIntensity = 1.25; // damage coeficient in the center of fire
coreDistance = 3.0; // how far can unit get damage
damageTime = 0.1; // how often is unit getting damage
// --- override of global particle quality params
// --- current values are in, for example:
// --- getNumber (((configFile >> "CfgVideoOptions" >> "Particles") select particlesQuality) >> "smokeGenMinDist");
smokeGenMinDist = 100; // for more info see "Changes dependent on distance"
smokeGenMaxDist = 500; // for more info see "Changes dependent on distance"
smokeSizeCoef = 2.0; // for more info see "Changes dependent on distance"
smokeIntervalCoef = 4.0; // for more info see "Changes dependent on distance"
};
Evaluation in definition of part-effect
There can be inserted string instead of number in most of parameters used in definition of part-effect. This string is evaluated and in this string can be used engine-defined variables from this list.
Behaviour of particles
Speed of rotation depends on
- initial rotation speed (parameters rotationVelocity and rotationVelocityVar)
- air friction (rotation is slowed more with bigger value of rubbing, rotation is slowed less with bigger value of weight)
Speed and direction of movement depends on
- initial speed of movement (parameters moveVelocity, moveVelocityVar and moveVelocityVarConst)
- wind/air friction (particle is more affected with bigger rubbing value, particle is less affected with bigger weight value)
- buoyancy (ratio between density of air and particle - density of particle = weight / volume)
- randomDirection parameters (randomDirectionPeriod, randomDirectionPeriodVar, randomDirectionIntensity and randomDirectionIntensityVar)
- collisions
Changes dependent on distance
Particles are simplified with bigger distance between particles and observer. Particles have a significant impact on performance and this helps to get better performance, so be careful with any change in the parameters below.
Parameters:
- smokeGenMinDist - defined in Definition of complex effect, default values in config class CfgDefaultSettings
- smokeGenMaxDist - defined in Definition of complex effect, default values in config class CfgDefaultSettings
- smokeSizeCoef - defined in Definition of complex effect, default values in config class CfgDefaultSettings
- smokeIntervalCoef - defined in Definition of complex effect, default values in config class CfgDefaultSettings
- dist - distance between camera and particle emitter, cut to interval <smokeGenMinDist, smokeGenMaxDist>
- currentZoom - zoom currently used
- smokeZoomCoef - defined in config class CfgDefaultSettings
Calculations:
- distCoef = (dist - smokeGenMinDist) / (smokeGenMaxDist - smokeGenMinDist)
- coef = distCoef * currentZoom * smokeZoomCoef
- coef is cut to interval <0,1>
- sizeCoef = 1.0 + coef * (smokeSizeCoef - 1.0)
- intervalCoef = 1.0 + coef * (smokeIntervalCoef - 1.0)
Changes in particles are made according to these coef values:
- sizeCoef - size of particle is multiplied by this value
- value is cut to interval <1, smokeSizeCoef>
- IntervalCoef - interval (how often is particle created by emitter) is multiplied by this value
- value is cut to interval <1, smokeIntervalCoef>
Calling of effect
There are two ways how to call a particle effect defined in config. You can use script or one of the engine-provided config parameters. Using of a config parameter (if there is one you can use) is usually recommended, because of better performance and an efficient use of engine-provided variables in PE definitions (see the list below).
Script
There is script command setParticleClass. This command can use only a class of PE. Example:
Config parameters
These engine-provided parameters have already set conditions for using of particle effect. For example parameter for exhaust effect is triggered when the engine of vehicle is running. Each parameter has engine-provided variables which can be used in some parts of definition of particle effect.
There are two types of emitter when you call an effect via config parameter. The type of emitter is specified in the engine for each parameter and behaviour of each emitter type is different:
- constant emitter (CE)
- variables used in definition of part-effect are evaluated when the emitter is created - they are the same during its entire life
- parameters ending with "Coef" in definition of part-effect are NOT evaluated
- real-time emitter (RE)
- variables in definition of part-effect are evaluated for each single particle
- parameters ending with "Coef" in definition of part-effect ARE evaluated
See the list of config parameters for more information.
Specials
Refraction (heat) effect
You can create refraction effect which simulates movement of hot air (around exhausts, fires, etc.). There is special texture for this purpose. How to create refract effect:
- in config-defined particle effect set:
particleShape = "\A3\data_f\ParticleEffects\Universal\Refract"; particleFSNtieth = 1; particleFSIndex = 0; particleFSFrameCount = 1; particleFSLoop = 0;
- in scripted particle effect set the first item in the ParticleArray (used by script command setParticleParams or drop) to: ["\A3\data_f\ParticleEffects\Universal\Refract", 1, 0, 1]
See also
Definition of an effect in a script:
- ParticleArray
- Particles Tutorial (Arma 2 & Arma 3)
- ParticleTemplates (Armed Assault)