so im working on a fighting-game in unity and i want to achieve an effect like this for our weapons.

we have laser-swords that look like this, and it would be totaly epic if we could achieve a trail effect like the one shown above.
actualy it has to look somewhat like that, not exactly.
BUT it has to work on mobile.
i dont know if i could achive this with a shader mady by scrumpy´s editor, but that would be perfect cause i know that defently works on mobile.
so what it needs to do is keep a part of the last 5 or so frames rendered, blendet over the current frame.
that would be nearly perfect.
if there is no way to do that via shader i gues i´ll have to animate something like this by hand, but this is what i am trying to avoid.
also the sword i would you looks like this:

it has transparency and self-illumination.
Replies
http://unity3d.com/support/documentation/Components/class-TrailRenderer.html
author: Nick Gronow (Stick)
using UnityEngine; using System.Collections; public class TrailArc : MonoBehaviour { int savedIndex; int pointIndex; // Material - Particle Shader with "Tint Color" property public Material material; // Emit public bool emit { get { return Emit; } set { Emit = value; } } bool Emit = true; bool emittingDone = false; //Minimum velocity (script terminates) public float minVel = 10; // Facing public bool faceCamera = true; // Lifetime of each segment public float lifetime = 1; float lifeTimeRatio = 1; float fadeOutRatio; // Colors public Color[] colors; // Widths public float[] widths; // Optimization public float pointDistance = 0.5f; float pointSqrDistance = 0; public int segmentsPerPoint = 4; float tRatio; // Print Output public bool printResults = false; public bool printSavedPoints = false; public bool printSegmentPoints = false; // Objects GameObject trail = null; Mesh mesh = null; Material trailMaterial = null; // Points Vector3[] saved; Vector3[] savedUp; int savedCnt = 0; Vector3[] points; Vector3[] pointsUp; int pointCnt = 0; // Segment Appearance Normalization int displayCnt = 0; float lastPointCreationTime = 0; float averageCreationTime = 0; float averageInsertionTime = 0; float elapsedInsertionTime = 0; // Initialization bool initialized = false; void Start () { if(gameObject.rigidbody.velocity.magnitude < minVel) Destroy(this); // Data Inititialization saved = new Vector3[60]; savedUp = new Vector3[saved.Length]; points = new Vector3[saved.Length * segmentsPerPoint]; pointsUp = new Vector3[points.Length]; tRatio = 1f / (segmentsPerPoint); pointSqrDistance = pointDistance * pointDistance; // Create the mesh object trail = new GameObject("Trail"); trail.transform.position = Vector3.zero; trail.transform.rotation = Quaternion.identity; trail.transform.localScale = Vector3.one; MeshFilter meshFilter = (MeshFilter) trail.AddComponent(typeof(MeshFilter)); mesh = meshFilter.mesh; trail.AddComponent(typeof(MeshRenderer)); trailMaterial = new Material(material); fadeOutRatio = trailMaterial.GetColor("_TintColor").a; trail.renderer.material = trailMaterial; } void printPoints() { if(savedCnt == 0) return; string s = "Saved Points at time " + Time.time + ":\n"; for(int i = 0; i < savedCnt; i++) s += "Index: " + i + "\tPos: " + saved[i] + "\n"; print(s); } void printAllPoints() { if(pointCnt == 0) return; string s = "Points at time " + Time.time + ":\n"; for(int i = 0; i < pointCnt; i++) s += "Index: " + i + "\tPos: " + points[i] + "\n"; 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; } if(printSavedPoints) printPoints(); if(printSegmentPoints) printAllPoints(); // 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[i]; 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; // Width float width; if(widths.Length == 0) width = 1; else if(widths.Length == 1) width = widths[0]; else if(widths.Length == 2) width = Mathf.Lerp(widths[1], widths[0], ratio); else { float widthRatio = widths.Length - 1 - ratio * (widths.Length-1); if(widthRatio == widths.Length-1) width = widths[widths.Length-1]; else { int min = (int) Mathf.Floor(widthRatio); float lerp = widthRatio - min; width = Mathf.Lerp(widths[min+0], widths[min+1], lerp); } } // Vertices if(faceCamera) { Vector3 from = i == displayCnt-1 ? points[i-1] : point; Vector3 to = i == displayCnt-1 ? point : points[i+1]; Vector3 pointDir = to - from; Vector3 vectorToCamera = cameraPos - point; Vector3 perpendicular = Vector3.Cross(pointDir, vectorToCamera).normalized; vertices[i * 2 + 0] = point + perpendicular * width * 0.5f; vertices[i * 2 + 1] = point - perpendicular * width * 0.5f; } else { vertices[i * 2 + 0] = point + pointsUp[i] * width * 0.5f; vertices[i * 2 + 1] = point - pointsUp[i] * width * 0.5f; } // UVs uvs[i * 2 + 0] = new Vector2(ratio , 0); uvs[i * 2 + 1] = new Vector2(ratio, 1); if(i > 0) { // Triangles int triIndex = (i - 1) * 6; int vertIndex = i * 2; triangles[triIndex+0] = vertIndex - 2; triangles[triIndex+1] = vertIndex - 1; triangles[triIndex+2] = vertIndex - 0; triangles[triIndex+3] = vertIndex + 0; triangles[triIndex+4] = vertIndex - 1; triangles[triIndex+5] = vertIndex + 1; } } trail.transform.position = Vector3.zero; trail.transform.rotation = Quaternion.identity; mesh.Clear(); mesh.vertices = vertices; mesh.colors = meshColors; mesh.uv = uvs; mesh.triangles = triangles; } catch(System.Exception e) { print(e); } } }I've always struggled with trails. <_<
need to wait till the attack animations are done so i can tweak it the way i want it to look like.
will post screens and maby vids when i get it to shine^^
/edit never mind i am just a noob it works great but the default color should not be black with 0 alpha ! default should not be something thats invisible !
dont know yet how it will look like with proper animation, but should turn out realy cool.
here is a small test i made.
sry for the quality, youtube smashed it.
[ame="
i gues this will eat up way too much performance for phones so i´ll give cupsster´s script a chance when we go for optimizing to the max.
right now we are spitting out beauty as much as we can, for we are creating the first trailer at the moment.
worth a look