Home Unity

lasersword trail how to?

greentooth
Offline / Send Message
Goeddy greentooth
so im working on a fighting-game in unity and i want to achieve an effect like this for our weapons.4515d1184941747-tales-of-symphonia-knight-ratatosk-dawn-new-world-tos2.jpg
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:
scrn96.jpg
it has transparency and self-illumination.

Replies

  • Maph
  • Goeddy
    Offline / Send Message
    Goeddy greentooth
    yeshhh exactly, thank you very much :]
  • cupsster
    Offline / Send Message
    cupsster polycounter lvl 11
    TrailArc.cs
    author: Nick Gronow (Stick)
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class TrailArc : MonoBehaviour
    5. {
    6. int savedIndex;
    7. int pointIndex;
    8. // Material - Particle Shader with "Tint Color" property
    9. public Material material;
    10. // Emit
    11. public bool emit
    12. {
    13. get { return Emit; }
    14. set { Emit = value; }
    15. }
    16. bool Emit = true;
    17. bool emittingDone = false;
    18. //Minimum velocity (script terminates)
    19. public float minVel = 10;
    20. // Facing
    21. public bool faceCamera = true;
    22. // Lifetime of each segment
    23. public float lifetime = 1;
    24. float lifeTimeRatio = 1;
    25. float fadeOutRatio;
    26.  
    27. // Colors
    28. public Color[] colors;
    29.  
    30. // Widths
    31. public float[] widths;
    32. // Optimization
    33. public float pointDistance = 0.5f;
    34. float pointSqrDistance = 0;
    35. public int segmentsPerPoint = 4;
    36. float tRatio;
    37.  
    38. // Print Output
    39. public bool printResults = false;
    40. public bool printSavedPoints = false;
    41. public bool printSegmentPoints = false;
    42. // Objects
    43. GameObject trail = null;
    44. Mesh mesh = null;
    45. Material trailMaterial = null;
    46. // Points
    47. Vector3[] saved;
    48. Vector3[] savedUp;
    49. int savedCnt = 0;
    50. Vector3[] points;
    51. Vector3[] pointsUp;
    52. int pointCnt = 0;
    53. // Segment Appearance Normalization
    54. int displayCnt = 0;
    55. float lastPointCreationTime = 0;
    56. float averageCreationTime = 0;
    57. float averageInsertionTime = 0;
    58. float elapsedInsertionTime = 0;
    59.  
    60. // Initialization
    61. bool initialized = false;
    62. void Start ()
    63. {
    64. if(gameObject.rigidbody.velocity.magnitude < minVel)
    65. Destroy(this);
    66. // Data Inititialization
    67. saved = new Vector3[60];
    68. savedUp = new Vector3[saved.Length];
    69. points = new Vector3[saved.Length * segmentsPerPoint];
    70. pointsUp = new Vector3[points.Length];
    71. tRatio = 1f / (segmentsPerPoint);
    72. pointSqrDistance = pointDistance * pointDistance;
    73. // Create the mesh object
    74. trail = new GameObject("Trail");
    75. trail.transform.position = Vector3.zero;
    76. trail.transform.rotation = Quaternion.identity;
    77. trail.transform.localScale = Vector3.one;
    78. MeshFilter meshFilter = (MeshFilter) trail.AddComponent(typeof(MeshFilter));
    79. mesh = meshFilter.mesh;
    80. trail.AddComponent(typeof(MeshRenderer));
    81. trailMaterial = new Material(material);
    82. fadeOutRatio = trailMaterial.GetColor("_TintColor").a;
    83. trail.renderer.material = trailMaterial;
    84. }
    85. void printPoints()
    86. {
    87. if(savedCnt == 0)
    88. return;
    89. string s = "Saved Points at time " + Time.time + ":\n";
    90. for(int i = 0; i < savedCnt; i++)
    91. s += "Index: " + i + "\tPos: " + saved[i] + "\n";
    92. print(s);
    93. }
    94.  
    95. void printAllPoints()
    96. {
    97. if(pointCnt == 0)
    98. return;
    99. string s = "Points at time " + Time.time + ":\n";
    100. for(int i = 0; i < pointCnt; i++)
    101. s += "Index: " + i + "\tPos: " + points[i] + "\n";
    102. print(s);
    103. }
    104.  
    105. void findCoordinates(int index)
    106. {
    107. if(index == 0 || index >= savedCnt-2)
    108. return;
    109. Vector3 P0 = saved[index-1];
    110. Vector3 P1 = saved[index];
    111. Vector3 P2 = saved[index+1];
    112. Vector3 P3 = saved[index+2];
    113. Vector3 T1 = 0.5f * (P2 - P0);
    114. Vector3 T2 = 0.5f * (P3 - P1);
    115. int pointIndex = index * segmentsPerPoint;
    116. for(int i = pointIndex; i < pointIndex+segmentsPerPoint; i++)
    117. {
    118. float t = (i-pointIndex) * tRatio;
    119. float t2 = t*t;
    120. float t3 = t2*t;
    121. float blend1 = 2*t3 - 3*t2 + 1;
    122. float blend2 = 3*t2 - 2*t3;
    123. float blend3 = t3 - 2*t2 + t;
    124. float blend4 = t3 - t2;
    125. int pntInd = i - segmentsPerPoint;
    126. points[pntInd] = blend1*P1 + blend2*P2 + blend3*T1 + blend4*T2;
    127. pointsUp[pntInd] = Vector3.Lerp(savedUp[index], savedUp[index+1], t);
    128. }
    129. pointCnt = pointIndex;
    130. }
    131. void Update ()
    132. {
    133. try
    134. {
    135. Vector3 position = transform.position;
    136. // Wait till the object is active (update called) and emitting
    137. if( ! initialized && Emit)
    138. {
    139. // Place the first point behind this as a starter projected point
    140. saved[savedCnt] = transform.TransformPoint(0,0,-pointDistance);
    141. savedUp[savedCnt] = transform.up;
    142. savedCnt++;
    143. // Place the second point at the current position
    144. saved[savedCnt] = position;
    145. savedUp[savedCnt] = transform.up;
    146. savedCnt++;
    147. // Begin tracking the saved point creation time
    148. lastPointCreationTime = Time.time;
    149. initialized = true;
    150. }
    151. if(printSavedPoints)
    152. printPoints();
    153. if(printSegmentPoints)
    154. printAllPoints();
    155. // Emitting - Designed for one-time use
    156. if( ! Emit )
    157. {
    158. if( ! emittingDone && pointCnt > 0 )
    159. {
    160. // Save two final points projected from the ending point
    161. saved[savedCnt] = transform.TransformPoint(0,0,pointDistance);
    162. savedUp[savedCnt] = transform.up;
    163. savedCnt++;
    164. findCoordinates(savedCnt-3);
    165. // This makes the trail fill the actual entire path
    166. saved[savedCnt] = transform.TransformPoint(0,0,pointDistance*2);
    167. savedUp[savedCnt] = transform.up;
    168. savedCnt++;
    169. findCoordinates(savedCnt-3);
    170. }
    171. emittingDone = true;
    172. }
    173. if(emittingDone)
    174. Emit = false;
    175. if(Emit)
    176. {
    177. // Do we save a new point?
    178. if( (saved[savedCnt-1] - position).sqrMagnitude > pointSqrDistance)
    179. {
    180. saved[savedCnt] = position;
    181. savedUp[savedCnt] = transform.up;
    182. savedCnt++;
    183.  
    184. // Calc the average point display time
    185. if(averageCreationTime == 0)
    186. averageCreationTime = Time.time - lastPointCreationTime;
    187. else
    188. {
    189. float elapsedTime = Time.time - lastPointCreationTime;
    190. averageCreationTime = (averageCreationTime + elapsedTime) * 0.5f;
    191. }
    192. averageInsertionTime = averageCreationTime * tRatio;
    193. lastPointCreationTime = Time.time;
    194.  
    195. // Calc the last saved segment coordinates
    196. if(savedCnt > 3)
    197. findCoordinates(savedCnt-3);
    198. }
    199. }
    200.  
    201. // Do we fade it out?
    202. if( ! Emit && displayCnt == pointCnt)
    203. {
    204. Color color = trailMaterial.GetColor("_TintColor");
    205. color.a -= fadeOutRatio * lifeTimeRatio * Time.deltaTime;
    206. if(color.a > 0)
    207. trailMaterial.SetColor("_TintColor", color);
    208. else
    209. {
    210. if(printResults)
    211. print("Trail effect ending with a segment count of: " + pointCnt);
    212. Destroy(trail);
    213. Destroy(gameObject);
    214. }
    215. return;
    216. }
    217. // Do we display any new points?
    218. if(displayCnt < pointCnt)
    219. {
    220. elapsedInsertionTime += Time.deltaTime;
    221. while(elapsedInsertionTime > averageInsertionTime)
    222. {
    223. if(displayCnt < pointCnt)
    224. displayCnt++;
    225. elapsedInsertionTime -= averageInsertionTime;
    226. }
    227. }
    228.  
    229. // Do we render this?
    230. if(displayCnt < 2)
    231. {
    232. trail.renderer.enabled = false;
    233. return;
    234. }
    235. trail.renderer.enabled = true;
    236. // Common data
    237. lifeTimeRatio = 1f / lifetime;
    238. Color[] meshColors;
    239. // Rebuild the mesh
    240. Vector3[] vertices = new Vector3[displayCnt * 2];
    241. Vector2[] uvs = new Vector2[displayCnt * 2];
    242. int[] triangles = new int[(displayCnt-1) * 6];
    243. meshColors = new Color[displayCnt * 2];
    244. float pointRatio = 1f / (displayCnt-1);
    245. Vector3 cameraPos = Camera.main.transform.position;
    246. for(int i = 0; i < displayCnt; i++)
    247. {
    248. Vector3 point = points[i];
    249. float ratio = i * pointRatio;
    250. // Color
    251. Color color;
    252. if(colors.Length == 0)
    253. color = Color.Lerp(Color.clear, Color.white, ratio);
    254. else if(colors.Length == 1)
    255. color = Color.Lerp(Color.clear, colors[0], ratio);
    256. else if(colors.Length == 2)
    257. color = Color.Lerp(colors[1], colors[0], ratio);
    258. else
    259. {
    260. float colorRatio = colors.Length - 1 - ratio * (colors.Length-1);
    261. if(colorRatio == colors.Length-1)
    262. color = colors[colors.Length-1];
    263. else
    264. {
    265. int min = (int) Mathf.Floor(colorRatio);
    266. float lerp = colorRatio - min;
    267. color = Color.Lerp(colors[min+0], colors[min+1], lerp);
    268. }
    269. }
    270. meshColors[i * 2] = color;
    271. meshColors[(i * 2) + 1] = color;
    272. // Width
    273. float width;
    274. if(widths.Length == 0)
    275. width = 1;
    276. else if(widths.Length == 1)
    277. width = widths[0];
    278. else if(widths.Length == 2)
    279. width = Mathf.Lerp(widths[1], widths[0], ratio);
    280. else
    281. {
    282. float widthRatio = widths.Length - 1 - ratio * (widths.Length-1);
    283. if(widthRatio == widths.Length-1)
    284. width = widths[widths.Length-1];
    285. else
    286. {
    287. int min = (int) Mathf.Floor(widthRatio);
    288. float lerp = widthRatio - min;
    289. width = Mathf.Lerp(widths[min+0], widths[min+1], lerp);
    290. }
    291. }
    292.  
    293. // Vertices
    294. if(faceCamera)
    295. {
    296. Vector3 from = i == displayCnt-1 ? points[i-1] : point;
    297. Vector3 to = i == displayCnt-1 ? point : points[i+1];
    298. Vector3 pointDir = to - from;
    299. Vector3 vectorToCamera = cameraPos - point;
    300. Vector3 perpendicular = Vector3.Cross(pointDir, vectorToCamera).normalized;
    301. vertices[i * 2 + 0] = point + perpendicular * width * 0.5f;
    302. vertices[i * 2 + 1] = point - perpendicular * width * 0.5f;
    303. }
    304. else
    305. {
    306. vertices[i * 2 + 0] = point + pointsUp[i] * width * 0.5f;
    307. vertices[i * 2 + 1] = point - pointsUp[i] * width * 0.5f;
    308. }
    309. // UVs
    310. uvs[i * 2 + 0] = new Vector2(ratio , 0);
    311. uvs[i * 2 + 1] = new Vector2(ratio, 1);
    312. if(i > 0)
    313. {
    314. // Triangles
    315. int triIndex = (i - 1) * 6;
    316. int vertIndex = i * 2;
    317. triangles[triIndex+0] = vertIndex - 2;
    318. triangles[triIndex+1] = vertIndex - 1;
    319. triangles[triIndex+2] = vertIndex - 0;
    320. triangles[triIndex+3] = vertIndex + 0;
    321. triangles[triIndex+4] = vertIndex - 1;
    322. triangles[triIndex+5] = vertIndex + 1;
    323. }
    324. }
    325. trail.transform.position = Vector3.zero;
    326. trail.transform.rotation = Quaternion.identity;
    327. mesh.Clear();
    328. mesh.vertices = vertices;
    329. mesh.colors = meshColors;
    330. mesh.uv = uvs;
    331. mesh.triangles = triangles;
    332. }
    333. catch(System.Exception e)
    334. {
    335. print(e);
    336. }
    337. }
    338. }
  • Elyaradine
    Offline / Send Message
    Elyaradine polycounter lvl 11
    If you get the look you want, please post screenshots! :D

    I've always struggled with trails. <_<
  • Goeddy
    Offline / Send Message
    Goeddy greentooth
    well i got it to work, but only with a dummy effect.
    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^^
  • warby
    Offline / Send Message
    warby polycounter lvl 18
    that script there is a huge troll face its not working at all

    /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 !
  • Goeddy
    Offline / Send Message
    Goeddy greentooth
    so i got the effect i wanted.
    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="http://www.youtube.com/watch?v=dbhEoqt1htM&quot;]trailtest.avi - YouTube[/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.
  • justifun
    Offline / Send Message
    justifun polycounter lvl 4
    There are 2 other free motion trail packages in the asset store. One is called pocket Rpg and the other is just called motion trails i think.

    worth a look
Sign In or Register to comment.