0% found this document useful (0 votes)
681 views5 pages

Unity Line Renderer Code

This script creates a trail effect by generating a series of points over time based on an object's position and rotation. It stores the points in an array, removes expired points, and inserts new points when needed. It builds a mesh from the points each frame, coloring and sizing the segments based on their age. The mesh is parented to an empty game object to render the trail.

Uploaded by

vermisterra
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
681 views5 pages

Unity Line Renderer Code

This script creates a trail effect by generating a series of points over time based on an object's position and rotation. It stores the points in an array, removes expired points, and inserts new points when needed. It builds a mesh from the points each frame, coloring and sizing the segments based on their age. The mesh is parented to an empty game object to render the trail.

Uploaded by

vermisterra
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 5

using UnityEngine; using System.

Collections; public class Trail : MonoBehaviour { // Material - Must be a particle material that has the "Tint Color" prop erty public Material material; Material instanceMaterial; // Emit public bool emit = true; bool emittingDone = false; // Lifetime of each segment public float lifeTime = 1; float lifeTimeRatio = 1; float fadeOutRatio; // Colors public Color[] colors; // Widths public float[] widths; // Segment creation data public float maxAngle = 2; public float minVertexDistance = 0.1f; public float maxVertexDistance = 1f; public float optimizeAngleInterval = 0.1f; public float optimizeDistanceInterval = 0.05f; public int optimizeCount = 30; // Object GameObject trailObj = null; Mesh mesh = null; // Points Point[] points = new Point[100]; int pointCnt = 0; void Start () { trailObj = new GameObject("Trail"); trailObj.transform.parent = null; trailObj.transform.position = Vector3.zero; trailObj.transform.rotation = Quaternion.identity; trailObj.transform.localScale = Vector3.one; MeshFilter meshFilter = (MeshFilter) trailObj.AddComponent(typeo f(MeshFilter)); mesh = meshFilter.mesh; trailObj.AddComponent(typeof(MeshRenderer)); instanceMaterial = new Material(material); fadeOutRatio = 1f / instanceMaterial.GetColor("_TintColor").a; trailObj.renderer.material = instanceMaterial; } void Update () { // Emitting - Designed for one-time use

if( ! emit ) emittingDone = true; if(emittingDone) emit = false; // Remove expired points for(int i = pointCnt-1; i >=0; i--) { Point point = points[i]; if(point == null || point.timeAlive > lifeTime) { points[i] = null; pointCnt--; } else break; } // Optimization if(pointCnt > optimizeCount) { maxAngle += optimizeAngleInterval; maxVertexDistance += optimizeDistanceInterval; optimizeCount += 1; } // Do we add any new points? if(emit) { if(pointCnt == 0) { points[pointCnt++] = new Point(transform); points[pointCnt++] = new Point(transform); } if(pointCnt == 1) insertPoint(); bool add = false; float sqrDistance = (points[1].position - transform.posi tion).sqrMagnitude; if(sqrDistance > minVertexDistance * minVertexDistance) { if(sqrDistance > maxVertexDistance * maxVertexDi stance) add = true; else if(Quaternion.Angle(transform.rotation, poi nts[1].rotation) > maxAngle) add = true; } if(add) { if(pointCnt == points.Length) System.Array.Resize(ref points, points.L ength + 50); insertPoint(); } if( ! add ) points[0].update(transform); }

// Do we render this? if(pointCnt < 2) { trailObj.renderer.enabled = false; return; } trailObj.renderer.enabled = true; Color[] meshColors; lifeTimeRatio = 1 / lifeTime; // Do we fade it out? if( ! emit ) { if(pointCnt == 0) return; Color color = instanceMaterial.GetColor("_TintColor"); color.a -= fadeOutRatio * lifeTimeRatio * Time.deltaTime ; if(color.a > 0) instanceMaterial.SetColor("_TintColor", color); else { Destroy(trailObj); Destroy(this); } return; } // Rebuild it Vector3[] vertices = new Vector3[pointCnt * 2]; Vector2[] uvs = new Vector2[pointCnt * 2]; int[] triangles = new int[(pointCnt-1) * 6]; meshColors = new Color[pointCnt * 2]; float uvMultiplier = 1 / (points[pointCnt-1].timeAlive - points[ 0].timeAlive); for(int i = 0; i < pointCnt; i++) { Point point = points[i]; float ratio = point.timeAlive * lifeTimeRatio; // Color Color color; if(colors.Length == 0) color = Color.Lerp(Color.white, Color.clear, rat io); else if(colors.Length == 1) color = Color.Lerp(colors[0], Color.clear, ratio ); else if(colors.Length == 2) color = Color.Lerp(colors[0], colors[1], ratio); else { float colorRatio = ratio * (colors.Length-1); int min = (int) Mathf.Floor(colorRatio); float lerp = Mathf.InverseLerp(min, min+1, color Ratio); color = Color.Lerp(colors[min], colors[min+1], l erp); }

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[0], widths[1], ratio); else { float widthRatio = ratio * (widths.Length-1); int min = (int) Mathf.Floor(widthRatio); float lerp = Mathf.InverseLerp(min, min+1, width Ratio); width = Mathf.Lerp(widths[min], widths[min+1], l erp); } trailObj.transform.position = point.position; trailObj.transform.rotation = point.rotation; vertices[i * 2] = trailObj.transform.TransformPoint(0,wi dth*0.5f,0); vertices[(i * 2) + 1] = trailObj.transform.TransformPoin t(0, -width*0.5f, 0); // UVs float uvRatio; uvRatio = (point.timeAlive - points[0].timeAlive) * uvMu ltiplier; uvs[i * 2] = new Vector2(uvRatio , 0); uvs[(i * 2) + 1] = new Vector2(uvRatio, 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 + 1; triangles[triIndex+4] = vertIndex + 0; triangles[triIndex+5] = vertIndex - 1; } } trailObj.transform.position = Vector3.zero; trailObj.transform.rotation = Quaternion.identity; mesh.Clear(); mesh.vertices = vertices; mesh.colors = meshColors; mesh.uv = uvs; mesh.triangles = triangles; } void insertPoint() { for(int i = pointCnt; i > 0; i--)

points[i] = points[i-1]; points[0] = new Point(transform); pointCnt++; } class Point { public float timeCreated = 0; public float timeAlive { get { return Time.time - timeCreated; } } public float fadeAlpha = 0; public Vector3 position = Vector3.zero; public Quaternion rotation = Quaternion.identity; public Point(Transform trans) { position = trans.position; rotation = trans.rotation; timeCreated = Time.time; } public void update(Transform trans) { position = trans.position; rotation = trans.rotation; timeCreated = Time.time; } } }

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy