You copied the Doc URL to your clipboard.

The firefly generator prefab

The firefly generator prefab manages the creation of the fireflies and updates them each frame. It is composed of a C# script for the update and a box collider that encloses the volume that each firefly can move in.

The script takes the number of fireflies to be generated as a parameter, and the prefab to instantiate the firefly object. Since the movement of the fireflies is random within the bounding box, it limits changes to a specific angle, away from the direction the firefly is moving. This ensures the firefly does not make sudden changes of direction.

To generate a random movement, a piecewise cubic Hermite interpolation is used to create the control points. The Hermite interpolation provides a smooth continuous function that behaves correctly even when different paths are connected together. The first derivative at the end points are also continuous so there are no sudden velocity changes.

This interpolation requires one control point each for the start and the end, and two tangents for each of the control points. Because these are generated randomly, the script can store three control points and two tangents. It uses the position of the first and second control points to define the first point tangent, and the second and third control points to define the tangent of the second control point.

At loading time, the script generates the following for each firefly:

  • An initial position.

  • An initial direction using the Unity function Random.onUnitSphere().

The following code shows how the control points are initialized:

_fireflySpline[i*_controlPoints] = initialPosition;
Vector3 randDirection = Random.onUnitSphere;
_fireflySpline[i*_controlPoints+1] = initialPosition + randDirection;
_fireflySpline[i*_controlPoints+2] = initialPosition + randDirection * 2.0f;

The initial control points lie on a straight line. The tangents are generated from these control points:

//The tangent for the first point is in the same direction as the initial direction vector
_fireflyTangents[i*_controlPoints] = randDirection;

//This code computes the tangent from the control point positions. It is shown here for 
// reference because it can be set to randDirection at initialization.
_fireflyTangents[i*_controlPoints+1] = (_fireflySpline[i*_controlPoints+2] - 
_fireflySpline[i*_controlPoints+1])/2 + (_fireflySpline[i*_controlPoints+1] - 
_fireflySpline[i*_controlPoints])/2;

To complete a firefly initialization, you must set the color of the firefly and the duration of the current path interval.

On each frame, the script updates the position of each firefly using the following code to compute the Hermite interpolation:

// t is the parameter that defines where in the curve the firefly is placed. It represents 
// the ratio of the time the firefly has traveled along the path to the total time. 
float t = _fireflyLifetime[i].y / _fireflyLifetime[i].x;

//Hermite interpolation parameters
Vector3 A = _fireflySpline[i*_controlPoints];
Vector3 B = _fireflySpline[i*_controlPoints+1];
float h00 = 2*Mathf.Pow(t,3) - 3*Mathf.Pow(t,2) + 1;
float h10 = Mathf.Pow(t,3) - 2*Mathf.Pow(t,2) + t;
float h01 = -2*Mathf.Pow(t,3) + 3*Mathf.Pow(t,2);
float h11 = Mathf.Pow(t,3) - Mathf.Pow(t,2);
//Firefly updated position
_fireflyObjects[i].transform.position = h00 * A + h10 * _fireflyTangents[i*_controlPoints] 
+ h01 * B + h11 * _fireflyTangents[i*_controlPoints+1];

If the firefly completed the whole piece of randomly generated path, the script creates a new random piece starting from the end of the current one:

//t > 1.0 indicates the end of the current path
if( t >= 1.0 )
{

	//Update the new position
	//Shift the second point to the first as well as the tangent
	_fireflySpline[i*_controlPoints] = _fireflySpline[i*_controlPoints+1];
	_fireflyTangents[i*_controlPoints] = _fireflyTangents[i*_controlPoints+1];

	//Shift the third point to the second, this point doesn't have a tangent
	_fireflySpline[i*_controlPoints+1] = _fireflySpline[i*_controlPoints+2];

	//Get new random control point within a certain angle from the current fly direction
	_fireflySpline[i*_controlPoints+2] = GetNewRandomControlPoint();

	//Compute the tangent for the central point
	_fireflyTangents[i*_controlPoints+1] = (_fireflySpline[i*_controlPoints+2] - 
	_fireflySpline[i*_controlPoints+1])/2 + (_fireflySpline[i*_controlPoints+1] - 
	_fireflySpline[i*_controlPoints])/2;

	//Set how long should take to navigate this part of path
	_fireflyLifetime[i].x = _fireflyMinLifetime;

	//Timer used to check how much we traveled along the path
	_fireflyLifetime[i].y = 0.0f;
}

Was this page helpful? Yes No