Cars and many other vehicles emit exhaust smoke as they convert fuel into power. You can use a particle system to add an exhaust as a nice finishing touch for a vehicle.
Exhaust smoke emerges from the pipe quite fast but then rapidly slows down on contact with the atmosphere. As it slows, it spreads out, becoming fainter and soon dissipating into the air. Since the exhaust gas is hot, it also rises slightly as it passes through the colder air surrounding it.
A particle of exhaust smoke must start off no larger than the width of the pipe but it will then grow in size considerably over its short lifetime. It will usually start off partly transparent and fade to total transparency as it mixes with the air. As regards dynamics, the particle will be emitted quite fast but then slow rapidly and will also lift upward slightly.
In the Shape module, select the Cone shape and set its Angle property to zero; the “cone” in this case will actually be a cylindrical pipe. The Radius of the pipe naturally depends on the size of the vehicle but you can usually set it by matching the radius Gizmo in the scene view to the vehicle model (eg, a car model will usually feature an exhaust pipe or a hole at the back whose size you can match). The radius actually determines quite a few things about the property settings you choose, such as the particle size and emission rate. For the purposes of this example, we will assume the vehicle is a car which follows Unity’s standard size convention of one world unit to one metre; the radius is thus set to about 0.05 or 5cm.
A suitable graphic for the smoke particle is provided by the Smoke4 material provided in the standard assets. If you don’t already have these installed then select Assets > Import Package > Particles from the menu. Then, go to the Renderer module of the particle system and set the Material property to Smoke4.
The default lifetime of five seconds is generally too long for car exhaust fumes, so you should open the Particle System module (which has the same name as the GameObject, eg, “Exhaust”) and set the Start Lifetime to about 2.5 seconds. Also in this module, set the Simulation Space to World and the Gravity Modifier to a small negative value, say about –0.1. Using a world simulation space allows the smoke to hang where it is produced even when the vehicle moves. The negative gravity effect causes the smoke particles to rise as if they are composed of hot gas. A nice extra touch is to use the small menu arrow next to Start Rotation to select the Random Between Two Constants option. Set the two values to 0 and 360, respectively, and the smoke particles will be randomly rotated as they are emitted. Having many particles that are identically aligned is very noticeable and detracts from the effect of a random, shapeless smoke trail.
At this stage, the smoke particles are starting to look realistic and the default emission rate creates a nice “chugging” effect of an engine. However, the smoke doesn’t billow outwards and dissipate as yet. Open the Color Over Lifetime module and click the top gradient stop on the right hand end of the gradient (this controls the transparency of “alpha” value of the color). Set the alpha value to zero and you should see the smoke particles fading to nothing in the scene. Depending on how clean your engine is, you may also want to reduce the alpha value of the gradient at the start; thick, dark smoke tends to suggest dirty, inefficient combustion.
As well as fading, the smoke should also increase in size as it escapes and you can easily create this effect with the Size Over Lifetime module. Open the module, select the curve and slide the curve handle at the left hand end to make the particles start off at a fraction of their full size. The exact size you choose depends on the size of the exhaust pipe but a value slightly larger than the pipe gives a good impression of escaping gas. (Starting the particles at the same size as the pipe suggests that the gas is being held to its shape by the pipe but of course, gas doesn’t have a defined shape.) Use the simulation of the particle system in the scene view to get a good visual impression of how the smoke looks. You may also want to increase the Start Size in the particle system module at this point if the smoke doesn’t disperse far enough to create the effect you want.
Finally, the smoke should also slow down as it disperses. An easy way to make this happen is with the Force Over Lifetime module. Open the module and set the Space option to Local and the Z component of the force to a negative value to indicate that the particles are pushed back by the force (the system emits the particles along the positive Z direction in the object’s local space). A value of about –0.75 works quite well for the system if the other parameters are set up as suggested above.
You can position the exhaust particle system by placing it on a child object of the main vehicle. For simple games, you can just enable the Play On Awake and Looping properties and let the system run. In most cases, however, you will probably want to vary at least the emission rate as the vehicle moves. This is firstly for authenticity (ie, an engine produces more smoke as it works harder) but it also helps to prevent the smoke particles from being spread out as the vehicle moves. A fast-moving vehicle with too low an emission rate will appear to produce distinct “puffs” of smoke, which is highly unrealistic.
You can vary the emission rate very easily from a script. If you have a variable in the script that represents the engine revs or the speed of the vehicle then you can simply multiply this value by a constant and assign the result to the ParticleSystem’s emissionRate property.
// C#
using UnityEngine;
using System.Collections;
public class PartScriptTestCS : MonoBehaviour {
public float engineRevs;
public float exhaustRate;
ParticleSystem exhaust;
void Start () {
exhaust = GetComponent<ParticleSystem>();
}
void Update () {
exhaust.emissionRate = engineRevs * exhaustRate;
}
}
// JS
var engineRevs: float;
var exhaustRate: float;
var exhaust: ParticleSystem;
function Start() {
exhaust = GetComponent.<ParticleSystem>();
}
function Update () {
exhaust.emissionRate = engineRevs * exhaustRate;
}
The basic scheme creates quite a convincing impression of exhaust smoke but you will probably have noticed that the “character” of the engine changes as you vary the parameters. An poorly tuned, inefficient engine tends to burn its fuel incompletely, resulting in heavy, dark smoke that persists for a long time in the air. This would be perfect for an old farm tractor but not for a high-performance sports car. For a “clean” engine, you should use small values for the lifetime, opacity and size increase of the particles. For a “dirty” engine, you should increase these values and perhaps use the Bursts property of the Emission module to create the impression of the engine spluttering.