void printPoints()
{
if(savedCnt == 0)
return;
string s = "Saved Points at time " + Time.time + ":
";
for(int i = 0; i < savedCnt; i++)
s += "Index: " + i + " Pos: " + saved + "
";
print(s);
}
void printAllPoints()
{
if(pointCnt == 0)
return;
string s = "oints at time " + Time.time + ":
";
for(int i = 0; i < pointCnt; i++)
s += "Index: " + i + " Pos: " + points + "
";
print(s);
}
void findCoordinates(int index)
{
if(index == 0 || index >= savedCnt-2)
return;
Vector3 P0 = saved[index-1];
Vector3 P1 = saved[index];
Vector3 P2 = saved[index+1];
Vector3 P3 = saved[index+2];
Vector3 T1 = 0.5f * (P2 - P0);
Vector3 T2 = 0.5f * (P3 - P1);
int pointIndex = index * segmentsPerPoint;
for(int i = pointIndex; i < pointIndex+segmentsPerPoint; i++)
{
float t = (i-pointIndex) * tRatio;
float t2 = t*t;
float t3 = t2*t;
float blend1 = 2*t3 - 3*t2 + 1;
float blend2 = 3*t2 - 2*t3;
float blend3 = t3 - 2*t2 + t;
float blend4 = t3 - t2;
int pntInd = i - segmentsPerPoint;
points[pntInd] = blend1*P1 + blend2*P2 + blend3*T1 + blend4*T2;
pointsUp[pntInd] = Vector3.Lerp(savedUp[index], savedUp[index+1], t);
}
pointCnt = pointIndex;
}
void Update ()
{
try
{
Vector3 position = transform.position;
// Wait till the object is active (update called) and emitting
if( ! initialized && Emit)
{
// Place the first point behind this as a starter projected point
saved[savedCnt] = transform.TransformPoint(0,0,-pointDistance);
savedUp[savedCnt] = transform.up;
savedCnt++;
// Place the second point at the current position
saved[savedCnt] = position;
savedUp[savedCnt] = transform.up;
savedCnt++;
// Begin tracking the saved point creation time
lastPointCreationTime = Time.time;
initialized = true;
}
// Emitting - Designed for one-time use
if( ! Emit )
{
if( ! emittingDone && pointCnt > 0 )
{
// Save two final points projected from the ending point
saved[savedCnt] = transform.TransformPoint(0,0,pointDistance);
savedUp[savedCnt] = transform.up;
savedCnt++;
findCoordinates(savedCnt-3);
// This makes the trail fill the actual entire path
saved[savedCnt] = transform.TransformPoint(0,0,pointDistance*2);
savedUp[savedCnt] = transform.up;
savedCnt++;
findCoordinates(savedCnt-3);
}
emittingDone = true;
}
if(emittingDone)
Emit = false;
if(Emit)
{
// Do we save a new point?
if( (saved[savedCnt-1] - position).sqrMagnitude > pointSqrDistance)
{
saved[savedCnt] = position;
savedUp[savedCnt] = transform.up;
savedCnt++;
// Calc the average point display time
if(averageCreationTime == 0)
averageCreationTime = Time.time - lastPointCreationTime;
else
{
float elapsedTime = Time.time - lastPointCreationTime;
averageCreationTime = (averageCreationTime + elapsedTime) * 0.5f;
}
averageInsertionTime = averageCreationTime * tRatio;
lastPointCreationTime = Time.time;
// Calc the last saved segment coordinates
if(savedCnt > 3)
findCoordinates(savedCnt-3);
}
}
// Do we fade it out?
if( ! Emit && displayCnt == pointCnt)
{
Color color = trailMaterial.GetColor("_TintColor");
color.a -= fadeOutRatio * lifeTimeRatio * Time.deltaTime;
if(color.a > 0)
trailMaterial.SetColor("_TintColor", color);
else
{
if(printResults)
print("Trail effect ending with a segment count of: " + pointCnt);
Destroy(trail);
Destroy(gameObject);
}
return;
}
// Do we display any new points?
if(displayCnt < pointCnt)
{
elapsedInsertionTime += Time.deltaTime;
while(elapsedInsertionTime > averageInsertionTime)
{
if(displayCnt < pointCnt)
displayCnt++;
elapsedInsertionTime -= averageInsertionTime;
}
}
// Do we render this?
if(displayCnt < 2)
{
trail.renderer.enabled = false;
return;
}
trail.renderer.enabled = true;
// Common data
lifeTimeRatio = 1f / lifetime;
Color[] meshColors;
// Rebuild the mesh
Vector3[] vertices = new Vector3[displayCnt * 2];
Vector2[] uvs = new Vector2[displayCnt * 2];
int[] triangles = new int[(displayCnt-1) * 6];
meshColors = new Color[displayCnt * 2];
float pointRatio = 1f / (displayCnt-1);
Vector3 cameraPos = Camera.main.transform.position;
for(int i = 0; i < displayCnt; i++)
{
Vector3 point = points;
float ratio = i * pointRatio;
// Color
Color color;
if(colors.Length == 0)
color = Color.Lerp(Color.clear, Color.white, ratio);
else if(colors.Length == 1)
color = Color.Lerp(Color.clear, colors[0], ratio);
else if(colors.Length == 2)
color = Color.Lerp(colors[1], colors[0], ratio);
else
{
float colorRatio = colors.Length - 1 - ratio * (colors.Length-1);
if(colorRatio == colors.Length-1)
color = colors[colors.Length-1];
else
{
int min = (int) Mathf.Floor(colorRatio);
float lerp = colorRatio - min;
color = Color.Lerp(colors[min+0], colors[min+1], lerp);
}
}
meshColors[i * 2] = color;
meshColors[(i * 2) + 1] = color;