Beispiel #1
0
 /// <summary>
 /// Updates points' positions from time to time.
 /// </summary>
 /// <param name="line"></param>
 /// <param name="deltaTime"></param>
 private void UpdatePoints(TrailGraphics trail, float deltaTime)
 {
     for (int i = 0; i < trail.points.Count; i++)
     {
         trail.points[i].Update(deltaTime);
     }
 }
Beispiel #2
0
 protected override void UpdateTrail(TrailGraphics trail, float deltaTime)
 {
     if (trail.points.Count <= 0 || !updateNow)
     {
         return;
     }
     Segment(trail.points.Count - 1, m_transform.position, trail);
     for (int i = trail.points.Count - 1; i > 0; i--)
     {
         Segment(i - 1, trail.points[i].position, trail);
     }
     updateNow = false;
 }
Beispiel #3
0
        /// <summary>
        /// Count the points whose life time have not passed yet.
        /// We do nothing to those whose life time have passed.
        /// Because we are using RingBuffer as an Object Pool :)
        /// </summary>
        /// <param name="trail"></param>
        /// <returns></returns>
        private int ActivePointsNumber(TrailGraphics trail)
        {
            int count = 0;

            for (int i = 0; i < trail.points.Count; i++)
            {
                if (trail.points[i].timeSoFar < parameter.lifeTime)
                {
                    count++;
                }
            }

            return(count);
        }
Beispiel #4
0
        private void Segment(int i, Vector3 pos, TrailGraphics trail)
        {
            Vector3 d   = pos - trail.points[i].position;
            float   mag = d.magnitude;

            if (mag <= 0.001f)
            {
                mag = 1f;
            }
            Vector3 temp = Vector3.zero;

            temp.x = pos.x - Vector3.Dot(right, d) * jointDistance * followScale / mag;
            temp.y = pos.y - Vector3.Dot(up, d) * jointDistance * followScale / mag;
            temp.z = pos.z - Vector3.Dot(forward, d) * jointDistance * followScale / mag;
            trail.points[i].position = temp;
        }
Beispiel #5
0
 /// <summary>
 /// Just in case the Emission is suddenly shut-down or activated.
 /// </summary>
 private void CheckEmitChange()
 {
     if (isEmitting != Emit)
     {
         isEmitting = Emit;
         if (isEmitting)
         {
             activeTrail            = new TrailGraphics(GetMaxPoints());
             activeTrail.activeSelf = true;
             OnStartEmit();
         }
         else
         {
             OnStopEmit();
             activeTrail.activeSelf = false;
             fadingTrails.Add(activeTrail);
             activeTrail = null;
         }
     }
 }
Beispiel #6
0
        /// <summary>
        /// De-constructor.
        /// </summary>
        protected virtual void OnDestroy()
        {
            totalTrailsCount--;
            if (totalTrailsCount == 0)
            {
                if (generatedMeshes != null && generatedMeshes.Count > 0)
                {
                    foreach (Mesh m in generatedMeshes)
                    {
#if UNITY_EDITOR
                        DestroyImmediate(m, true);
#else
                        Destroy(m);
#endif
                    }
                }
                generatedMeshes = null;
                mat2Trail.Clear();
                mat2Trail = null;
            }

            if (activeTrail != null)
            {
                activeTrail.Dispose();
                activeTrail = null;
            }

            if (fadingTrails != null)
            {
                foreach (TrailGraphics fadingTrail in fadingTrails)
                {
                    if (fadingTrail != null)
                    {
                        fadingTrail.Dispose();
                    }
                }
                fadingTrails.Clear();
            }
        }
Beispiel #7
0
        /// <summary>
        /// De-constructor.
        /// </summary>
        protected virtual void OnDestroy()
        {
            totalTrailsCount--;

            if (activeTrail != null)
            {
                activeTrail.Dispose();
                activeTrail = null;
            }

            if (fadingTrails != null)
            {
                foreach (TrailGraphics fadingTrail in fadingTrails)
                {
                    if (fadingTrail != null)
                    {
                        fadingTrail.Dispose();
                    }
                }
                fadingTrails.Clear();
            }
        }
Beispiel #8
0
        /// <summary>
        /// Serves as a variable-initializer.
        /// </summary>
        protected virtual void Awake()
        {
            totalTrailsCount++;
            parameter.isCross = parameter.trailType == TrailType.Cross;
            ///The only Guy :) Last Titan Standing.
            if (totalTrailsCount == 1)
            {
                //mat2Trail = new Dictionary<Material, List<TrailGraphics>>();
                //generatedMeshes = new List<Mesh>();
            }

            fadingTrails = new List <TrailGraphics>();
            m_transform  = transform;
            isEmitting   = Emit;

            if (isEmitting)
            {
                activeTrail            = new TrailGraphics(GetMaxPoints(), parameter.isCross);
                activeTrail.activeSelf = true;
                OnStartEmit();
            }
        }
Beispiel #9
0
        /// <summary>
        /// Serves as a variable-initializer.
        /// </summary>
        protected virtual void Awake()
        {
            totalTrailsCount++;
            ///The only Guy :) Last Titan Standing.
            if (totalTrailsCount == 1)
            {
                mat2Trail       = new Dictionary <Material, List <TrailGraphics> >();
                generatedMeshes = new List <Mesh>();
            }

            fadingTrails = new List <TrailGraphics>();
            m_transform  = transform;
            isEmitting   = Emit;

            if (parameter.orientationType == TrailOrientation.LookAt && parameter.lookAt == null)
            {
                if (Camera.main != null)
                {
                    parameter.lookAt = Camera.main.transform;
                    Debug.Log(gameObject.name + ": 未指定面向物体, 因此默认面向主摄像机. ");
                }
                else
                {
                    parameter.orientationType = TrailOrientation.Local;
                    parameter.forwardOverride = Vector3.forward;
                    Debug.Log(gameObject.name + ": 无法指定当前Trail的朝向, 为避免错误转化为Local. ");
                }
            }

            if (isEmitting)
            {
                activeTrail            = new TrailGraphics(GetMaxPoints());
                activeTrail.activeSelf = true;
                OnStartEmit();
            }
        }
Beispiel #10
0
 /// <summary>
 /// Just in case the Emission is suddenly shut-down or activated.
 /// </summary>
 private void CheckEmitChange()
 {
     if (isEmitting != Emit)
     {
         isEmitting = Emit;
         if (isEmitting)
         {
             activeTrail            = new TrailGraphics(GetMaxPoints(), parameter.isCross);
             activeTrail.activeSelf = true;
             OnStartEmit();
         }
         else
         {
             if (activeTrail == null)
             {
                 return;
             }
             OnStopEmit();
             activeTrail.activeSelf = false;
             fadingTrails.Add(activeTrail);
             activeTrail = null;
         }
     }
 }
Beispiel #11
0
        protected override void UpdateTrail(TrailGraphics trail, float deltaTime)
        {
            if (!trail.activeSelf)
            {
                return;
            }

            int trailPointIdx = 0;

            for (int i = 0; i < controlPoints.Count; i++)
            {
                trail.points[trailPointIdx].position = controlPoints[i].position;

                trail.points[trailPointIdx].forwardDirection = controlPoints[i].forward;

                trailPointIdx++;
                if (i < controlPoints.Count - 1)
                {
                    Vector3 cp1, cp2;
                    float   distance = Vector3.Distance(controlPoints[i].position, controlPoints[i + 1].position) / 2;
                    if (i == 0)
                    {
                        cp1 = controlPoints[i].position + (controlPoints[i + 1].position - controlPoints[i].position).normalized * distance;
                    }
                    else
                    {
                        cp1 = controlPoints[i].position + (controlPoints[i + 1].position - controlPoints[i - 1].position).normalized * distance;
                    }

                    int nextIdx = i + 1;

                    if (nextIdx == controlPoints.Count - 1)
                    {
                        cp2 = controlPoints[nextIdx].position + (controlPoints[nextIdx - 1].position - controlPoints[nextIdx].position).normalized * distance;
                    }
                    else
                    {
                        cp2 = controlPoints[nextIdx].position + (controlPoints[nextIdx - 1].position - controlPoints[nextIdx + 1].position).normalized * distance;
                    }

                    TrailPoint current = trail.points[trailPointIdx - 1];
                    TrailPoint next    = trail.points[trailPointIdx + pointsInMiddle];

                    for (int j = 0; j < pointsInMiddle; j++)
                    {
                        float t = (((float)j + 1) / ((float)pointsInMiddle + 1));
                        trail.points[trailPointIdx].position  = Bezier.CalculateCubic(t, controlPoints[i].position, cp1, cp2, controlPoints[i + 1].position);
                        trail.points[trailPointIdx].timeSoFar = Mathf.Lerp(current.timeSoFar, next.timeSoFar, t);

                        trail.points[trailPointIdx].forwardDirection = Vector3.Lerp(current.forwardDirection, next.forwardDirection, t);

                        trailPointIdx++;
                    }
                }
            }

            int lastCPIdx   = (pointsInMiddle + 1) * (controlPoints.Count - 1);
            int prevCPIdx   = lastCPIdx - pointsInMiddle - 1;
            int activeCount = lastCPIdx + 1;

            float distance2Src = trail.points[prevCPIdx].distance2Src;

            for (int i = prevCPIdx + 1; i < activeCount; i++)
            {
                distance2Src += Vector3.Distance(trail.points[i - 1].position, trail.points[i].position);
                trail.points[i].distance2Src = distance2Src;
            }
        }
Beispiel #12
0
        /// <summary>
        /// Help a trail generate its own Mesh.
        /// </summary>
        /// <param name="trail"></param>
        private void GenerateMesh(TrailGraphics trail)
        {
            trail.mesh.Clear(false);
            Vector3 cameraForward = Camera.main.transform.forward;

            ///Determine the trail forward direction.
            switch (parameter.orientationType)
            {
            case TrailOrientation.LookAt:
                cameraForward = (parameter.lookAt.position - m_transform.position).normalized;
                break;

            case TrailOrientation.Local:
                cameraForward = m_transform.forward;
                break;

            case TrailOrientation.World:
                cameraForward = parameter.forwardOverride.normalized;
                break;

            default:
                break;
            }

            trail.activeCount = ActivePointsNumber(trail);

            ///No way to draw a Mesh with only 2 vertices or even less. Exit.
            if (trail.activeCount < 2)
            {
                return;
            }

            int vertIdx = 0;

            for (int i = 0; i < trail.points.Count; i++)
            {
                TrailPoint tp           = trail.points[i];
                float      timeFraction = tp.timeSoFar / parameter.lifeTime;

                if (timeFraction > 1)
                {
                    continue;
                }

                if (parameter.orientationType == TrailOrientation.Local)
                {
                    cameraForward = tp.forwardDirection;
                }

                Vector3 cross = Vector3.zero;

                if (i < trail.points.Count - 1)
                {
                    cross = Vector3.Cross((trail.points[i + 1].position - tp.position).normalized, cameraForward).normalized;
                }
                else
                {
                    cross = Vector3.Cross((tp.position - trail.points[i - 1].position).normalized, cameraForward).normalized;
                }

                Color c = parameter.colorOverLife.Evaluate(1 - (float)vertIdx / (float)trail.activeCount / 2f);
                float s = parameter.sizeOverLife.Evaluate(timeFraction);

                trail.vertices[vertIdx] = tp.position + cross * s;
                trail.uvs[vertIdx]      = new Vector2(tp.distance2Src / parameter.quadScaleFactor, 0.0f);
                trail.normals[vertIdx]  = cameraForward;
                trail.colors[vertIdx]   = c;
                vertIdx++;
                trail.vertices[vertIdx] = tp.position - cross * s;
                trail.uvs[vertIdx]      = new Vector2(tp.distance2Src / parameter.quadScaleFactor, 1.0f);
                trail.normals[vertIdx]  = cameraForward;
                trail.colors[vertIdx]   = c;
                vertIdx++;
            }

            ///"Stack" all redundant vertices into the termination position.
            Vector2 termination = trail.vertices[vertIdx - 1];

            for (int i = vertIdx; i < trail.vertices.Length; i++)
            {
                trail.vertices[i] = termination;
            }

            ///Now let's focus on triangle array ...
            int triIdx = 0;

            for (int i = 0, imax = 2 * (trail.activeCount - 1); i < imax; i++)
            {
                ///Ok, start point.
                if (i % 2 == 0)
                {
                    trail.indices[triIdx++] = i;
                    trail.indices[triIdx++] = i + 1;
                    trail.indices[triIdx++] = i + 2;
                }
                else                ///Reverse the process.
                {
                    trail.indices[triIdx++] = i + 2;
                    trail.indices[triIdx++] = i + 1;
                    trail.indices[triIdx++] = i;
                }
            }

            ///"Squash" all the redundant vertices and triangle arrays.
            int termIdx = trail.indices[triIdx - 1];

            for (int i = triIdx; i < trail.indices.Length; i++)
            {
                trail.indices[i] = termIdx;
            }

            ///So now comes the Exciting part. CONG!
            trail.mesh.vertices = trail.vertices;
            ///Setting Indices array directly to mesh also works.
            trail.mesh.SetIndices(trail.indices, MeshTopology.Triangles, 0);
            trail.mesh.uv      = trail.uvs;
            trail.mesh.normals = trail.normals;
            trail.mesh.colors  = trail.colors;
        }
Beispiel #13
0
 protected virtual void UpdateTrail(TrailGraphics trail, float deltaTime)
 {
 }
Beispiel #14
0
        /// <summary>
        /// Help a trail generate its own Mesh.
        /// </summary>
        /// <param name="trail"></param>
        private void GenerateMesh(TrailGraphics trail)
        {
            trail.mesh.Clear(false);
            Vector3 cameraForward = GetFacing();

            trail.activeCount = ActivePointsNumber(trail);

            /// No way to draw a Mesh with only 2 vertices or even less. Exit.
            if (trail.activeCount < 2)
            {
                return;
            }

            int     vertIdx   = 0;
            Vector3 lastCross = cameraForward;

            if (parameter.trailType == TrailType.Vertical || parameter.isCross)
            {
                for (int i = 0; i < trail.points.Count; i++)
                {
                    TrailPoint tp           = trail.points[i];
                    float      timeFraction = tp.timeSoFar / parameter.lifeTime;

                    if (timeFraction > 1)
                    {
                        continue;
                    }

                    if (parameter.orientationType == TrailOrientation.Local)
                    {
                        cameraForward = tp.forwardDirection;
                    }

                    Vector3 cross   = Vector3.zero;
                    Vector3 moveDir = cameraForward;

                    if (i < trail.points.Count - 1)
                    {
                        moveDir = (trail.points[i + 1].position - tp.position).normalized;
                    }
                    else
                    {
                        moveDir = (tp.position - trail.points[i - 1].position).normalized;
                    }
                    cross = Vector3.Cross(moveDir, cameraForward).normalized;

                    if (cross.magnitude < 0.9f)
                    {
                        cross = lastCross.normalized;
                    }

                    else if (Vector3.Dot(cross, lastCross) < 0f)
                    {
                        cross     = -cross;
                        lastCross = -cross;
                    }

                    else
                    {
                        lastCross = cross;
                    }

                    Color c = parameter.colorOverLife.Evaluate(1 - (float)vertIdx / (float)trail.activeCount / 2f);
                    float s = parameter.sizeOverLife.Evaluate(timeFraction);

                    float   uvx    = parameter.isTile ? tp.distance2Src / parameter.quadScaleFactor : 1 - timeFraction;
                    Vector3 offset = cross * s * parameter.sizeMultiplier;
                    trail.vertices[vertIdx] = tp.position + offset;
                    trail.uvs[vertIdx]      = new Vector2(uvx, 0.0f);
                    trail.normals[vertIdx]  = cameraForward;
                    trail.colors[vertIdx]   = c;
                    vertIdx++;
                    trail.vertices[vertIdx] = tp.position - offset;
                    trail.uvs[vertIdx]      = new Vector2(uvx, 1.0f);
                    trail.normals[vertIdx]  = cameraForward;
                    trail.colors[vertIdx]   = c;
                    vertIdx++;
                }
            }

            int oldVertIdx = vertIdx;

            lastCross = cameraForward;

            if (parameter.trailType == TrailType.Horizontal || parameter.isCross)
            {
                for (int i = 0; i < trail.points.Count; i++)
                {
                    TrailPoint tp           = trail.points[i];
                    float      timeFraction = tp.timeSoFar / parameter.lifeTime;

                    if (timeFraction > 1)
                    {
                        continue;
                    }

                    if (parameter.orientationType == TrailOrientation.Local)
                    {
                        cameraForward = tp.forwardDirection;
                    }

                    Vector3 cross = cameraForward;

                    Color c = parameter.colorOverLife.Evaluate(1 - ((float)vertIdx - oldVertIdx) / (float)trail.activeCount / 2f);
                    float s = parameter.sizeOverLife.Evaluate(timeFraction);

                    float   uvx    = parameter.isTile ? tp.distance2Src / parameter.quadScaleFactor : 1 - timeFraction;
                    Vector3 offset = cross * s * parameter.sizeMultiplier;
                    trail.vertices[vertIdx] = tp.position + offset;
                    trail.uvs[vertIdx]      = new Vector2(uvx, 0.0f);
                    trail.normals[vertIdx]  = cameraForward;
                    trail.colors[vertIdx]   = c;
                    vertIdx++;
                    trail.vertices[vertIdx] = tp.position - offset;
                    trail.uvs[vertIdx]      = new Vector2(uvx, 1.0f);
                    trail.normals[vertIdx]  = cameraForward;
                    trail.colors[vertIdx]   = c;
                    vertIdx++;
                }
            }

            /// "Stack" all redundant vertices into the termination position.
            Vector3 termination = trail.vertices[vertIdx - 1];

            for (int i = vertIdx; i < trail.vertices.Length; i++)
            {
                trail.vertices[i] = termination;
            }

            /// Now let's focus on triangle array ...
            int triIdx = 0;

            for (int i = 0, imax = 2 * (trail.activeCount - 1); i < imax; i++)
            {
                /// Ok, start point.
                if (i % 2 == 0)
                {
                    trail.indices[triIdx++] = i;
                    trail.indices[triIdx++] = i + 1;
                    trail.indices[triIdx++] = i + 2;
                }
                else                /// Reverse the process.
                {
                    trail.indices[triIdx++] = i + 2;
                    trail.indices[triIdx++] = i + 1;
                    trail.indices[triIdx++] = i;
                }
            }

            if (parameter.isCross)
            {
                for (int i = 2 * trail.activeCount, imax = 4 * trail.activeCount - 2; i < imax; i++)
                {
                    if (i % 2 == 0)
                    {
                        trail.indices[triIdx++] = i;
                        trail.indices[triIdx++] = i + 1;
                        trail.indices[triIdx++] = i + 2;
                    }
                    else
                    {
                        trail.indices[triIdx++] = i + 2;
                        trail.indices[triIdx++] = i + 1;
                        trail.indices[triIdx++] = i;
                    }
                }
            }

            /// "Squash" all the redundant vertices and triangle arrays.
            int termIdx = trail.indices[triIdx - 1];

            for (int i = triIdx; i < trail.indices.Length; i++)
            {
                trail.indices[i] = termIdx;
            }

            /// So now comes the Exciting part. CONG!
            trail.mesh.vertices = trail.vertices;
            /// Setting Indices array directly to mesh also works.
            trail.mesh.SetIndices(trail.indices, MeshTopology.Triangles, 0);
            trail.mesh.uv      = trail.uvs;
            trail.mesh.normals = trail.normals;
            trail.mesh.colors  = trail.colors;
        }