TronTrailをC#にした
プロシージャルなメッシュを作った方が幅が広がりそうなので、入門的な感じで。
マテリアルとテクスチャを用意しておいてそれを使う。
using UnityEngine; using System.Collections; public class TrailMain : MonoBehaviour { GameObject m_TrailObject = null; // Use this for initialization void Start () { Material mat = Resources.Load("Trail/trail_mat") as Material; Texture2D tex = Resources.Load("Trail/trail") as Texture2D; m_TrailObject = Trail.Create(mat, tex); } // Update is called once per frame void Update () { m_TrailObject.transform.position = new Vector3(10.0f*Mathf.Cos(Time.time), 0, 10.0f*Mathf.Sin(Time.time)); } }
using UnityEngine; using System.Collections; using System.Collections.Generic; /** * @brief 軌跡. */ public class Trail : MonoBehaviour { public static GameObject Create(Material mat, Texture2D tex) { GameObject go = new GameObject("Trail"); go.AddComponent<Trail>(); go.AddComponent<MeshFilter>(); MeshRenderer mr = go.AddComponent<MeshRenderer>(); mr.material = mat; mr.material.mainTexture = tex; return go; } class TrailSection { Vector3 m_Position = Vector3.zero; Vector3 m_UpDir = Vector3.zero; float m_Time = 0.0f; public Vector3 Positioin { get { return m_Position; } set { m_Position = value; } } public Vector3 UpDir { get { return m_UpDir; } set { m_UpDir = value; } } public float Time { get { return m_Time; } set { m_Time = value; } } } float m_Height = 2.0f; float m_Time = 2.0f; bool m_AlwaysUp = false; float m_MinDistance = 0.1f; Color m_StartColor = Color.white; Color m_EndColor = new Color(1.0f, 1.0f, 1.0f, 0.0f); List<TrailSection> m_TrailSectionList = null; void Awake () { m_TrailSectionList = new List<TrailSection>(); } // Update is called once per frame void LateUpdate () { Vector3 pos = gameObject.transform.position; float now = Time.time; RemoveOldSection(now); AddNewSection(pos, now); RebuildMesh(); } void RemoveOldSection(float now) { int section_count = m_TrailSectionList.Count; while(section_count > 0 && now > m_TrailSectionList[section_count-1].Time + m_Time) { m_TrailSectionList.RemoveAt(section_count-1); --section_count; } } void AddNewSection(Vector3 pos, float now) { if(m_TrailSectionList.Count == 0 || (m_TrailSectionList[0].Positioin - pos).sqrMagnitude > m_MinDistance * m_MinDistance) { TrailSection section = new TrailSection(); section.Positioin = pos; if(m_AlwaysUp) { section.UpDir = Vector3.up; } else { section.UpDir = gameObject.transform.TransformDirection(Vector3.up); } section.Time = now; m_TrailSectionList.Insert(0, section); } } void RebuildMesh() { MeshFilter meshFilter = GetComponent<MeshFilter>(); Mesh mesh = meshFilter.mesh; mesh.Clear(); int count = m_TrailSectionList.Count; if(count < 2) { return; } Vector3 [] vertices = new Vector3[count*2]; Color [] colors = new Color[count*2]; Vector2 [] uv = new Vector2[count*2]; TrailSection prevSection = m_TrailSectionList[0]; TrailSection curSection = m_TrailSectionList[0]; Matrix4x4 localTransform = gameObject.transform.worldToLocalMatrix; // generate vertex, uv and colors for(int i = 0; i < count; ++i) { prevSection = curSection; curSection = m_TrailSectionList[i]; float u = 0.0f; if(i != 0) { u = Mathf.Clamp01((Time.time - curSection.Time)/m_Time); } Vector3 upDir = curSection.UpDir; vertices[i*2+0] = localTransform.MultiplyPoint(curSection.Positioin); vertices[i*2+1] = localTransform.MultiplyPoint(curSection.Positioin+upDir*m_Height); uv[i*2+0] = new Vector2(u, 0.0f); uv[i*2+1] = new Vector2(u, 1.0f); Color interpolatedColor = Color.Lerp(m_StartColor, m_EndColor, u); colors[i*2+0] = interpolatedColor; colors[i*2+1] = interpolatedColor; } // generate triangles indices int [] triangles = new int[(count-1)*2*3]; for(int i = 0; i < triangles.Length/6; ++i) { triangles[i*6+0] = i*2+0; triangles[i*6+1] = i*2+1; triangles[i*6+2] = i*2+2; triangles[i*6+3] = i*2+2; triangles[i*6+4] = i*2+1; triangles[i*6+5] = i*2+3; } mesh.vertices = vertices; mesh.colors = colors; mesh.uv = uv; mesh.triangles = triangles; } }