Programming Custom Car Effects

This post covers the custom effects that take place on the car such as particle effects, emission changes etc…

All custom effects are contained within one script placed on the player’s car object.

Fake Body Rotation

When the player turns the car, the cars body ‘rotates’ from side to side much like a aircraft banking around a corner. In Velicous racing this body roll is completely  cosmetic and only in place for visual feedback.

The body roll method uses the players input and a constant roll value to create a scalar value that ranges from zero to maximum roll. This value is then converted to a quaternion rotation to avoid gimbal lock problems, finally the quaternion value is apply to the transform by multiplying it with the cars current rotation quaternion.

Video showing the bank angle working, notice how the car rolls as it turns(the effect have been amplified for this video to make it more obvious).

Code Snippet,

//'Bank' the body
private void FakeRotation(float _horizontalInput)
{
 float _rotation = MaxBankAngle * _horizontalInput;
 Quaternion _QRotation = Quaternion.Euler(new Vector3(0, 0, -_rotation));
 VehicleGraphics.transform.rotation = transform.rotation * _QRotation;
}

Engine Exhaust

The engine exhaust method is responsible for controlling the direction of the exhaust particle system and controlling its rate of emission.

The method itself works much like the body roll method in that it takes in the players input and outputs quaternion rotation, which is eventually used to control the direction of the exhaust.

The method does however carry out some other checks, the first of which is to check if the player is grounded. This is because the player cannot use the engine when they are grounded, thus the emission rate should be set back to default whenever the car is not grounded no matter the players input.

The other check that this method carries out is to check whether the player is boosting or not, this is because a secondary particle system is fired whenever the player is boosting to give some extra visual feedback.

Code Snippet with comments to explain,

private void EngineExhaust(float _horizontalInput, float _verticalInput, bool _grounded, bool _boosting)
{
 //Calculate a rotation based on players input
 float _rotation = -MaxExhaustAngle * _horizontalInput;
 //Loop through all of the engine particle system, if there are multiple engines
 for (int i = 0; i < EngineParticleSystems.Length; i++)
 {
  //Check if the player is boosting
  if(_boosting == true)
  {
   //Activate Boost Particle Effect
   BoostParticleSystems[i].Play();
  } else
  { //De-activate Boost Particle Effect
   BoostParticleSystems[i].Stop();
  }
  //Create a quaternion
  Quaternion _QRotation = Quaternion.Euler(new Vector3(0, _rotation, 0));
  //Apply the rotation to all particles in the loop
  EngineParticleSystems[i].transform.rotation = transform.rotation * _QRotation;
  //Create a temporory copy so we can adjust the private value emission
  ParticleSystem temp = EngineParticleSystems[i];
  //Adjust the value
  var tempEm = temp.emission;
  //Check if we are grounded
  if (_grounded == true)
  {
   //We are grounded set a emission rate based on input
   tempEm.rateOverTime = storedEmission + (MaxExhaustEmission * _verticalInput);
  } else
  {
   //Not grounded default emission
   tempEm.rateOverTime = storedEmission;
  }
  //Apply the new emissions
  EngineParticleSystems[i] = temp;
 }
}

Brake Lights

The brake light method is responsible for changing the emission map whenever the player braks,  because some parts car model share emission maps simply increasing the value of emissions would cause other parts of the car to glow and give undesired results. For this reason instead I instead swap the entire material for certain parts of the car, this secondary material has the higher emission value which is required. The swap is contained within a loop just so that multiple break lights can be added.

private void BrakingLights(float _verticalInput)
{
 if(_verticalInput < 0)
 {
  foreach(GameObject light in Lights)
  {
   light.GetComponent<MeshRenderer>().material.SetTexture("_EmissionMap", brakingEmssionMap);
  }
 } else
 if (_verticalInput >= 0)
 {
  foreach (GameObject light in Lights)
  {
   light.GetComponent<MeshRenderer>().material.SetTexture("_EmissionMap", defaultEmssionMap);
  }
 }
}

Sparks on Collide Method

Finally the sparks on collide method is a simply method that is activated each time the players object collides with another object, a flow chart explains the logic.

New-Mind-Map (15)

And the code,

private void OnCollisionEnter(Collision collision)
{
 foreach(ContactPoint contact in collision)
 {
  SparksOnCollide(contact.point, contact.normal);
 }
}
private void SparksOnCollide(Vector3 _position, Vector3 _rotation)
{
 bottomOutSparks.transform.position = _position;
 bottomOutSparks.transform.rotation = Quaternion.Euler(_rotation);
 bottomOutSparks.time = 0;
 bottomOutSparks.Play();
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

Up ↑

%d bloggers like this: