Exemple #1
0
        public void GenerateLightningBoltStandard(LightningBolt bolt, Vector3 start, Vector3 end, int generation, int totalGenerations, float offsetAmount, LightningBoltParameters p)
        {
            if (generation < 1)
            {
                return;
            }

            LightningBoltSegmentGroup group = bolt.AddGroup();

            group.Segments.Add(new LightningBoltSegment {
                Start = start, End = end
            });

            // every generation, get the percentage we have gone down and square it, this makes lines thinner
            float widthMultiplier = (float)generation / (float)totalGenerations;

            widthMultiplier *= widthMultiplier;

            Vector3 randomVector;

            group.LineWidth          = p.TrunkWidth * widthMultiplier;
            group.Generation         = generation;
            group.Color              = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(255.0f * widthMultiplier));
            group.EndWidthMultiplier = p.EndWidthMultiplier * p.ForkEndWidthMultiplier;
            if (offsetAmount <= 0.0f)
            {
                offsetAmount = (end - start).magnitude * p.ChaosFactor;
            }

            while (generation-- > 0)
            {
                int previousStartIndex = group.StartIndex;
                group.StartIndex = group.Segments.Count;
                for (int i = previousStartIndex; i < group.StartIndex; i++)
                {
                    start = group.Segments[i].Start;
                    end   = group.Segments[i].End;

                    // determine a new direction for the split
                    Vector3 midPoint = (start + end) * 0.5f;

                    // adjust the mid point to be the new location
                    RandomVector(bolt, ref start, ref end, offsetAmount, p.Random, out randomVector);
                    midPoint += randomVector;

                    // add two new segments
                    group.Segments.Add(new LightningBoltSegment {
                        Start = start, End = midPoint
                    });
                    group.Segments.Add(new LightningBoltSegment {
                        Start = midPoint, End = end
                    });

                    CreateFork(bolt, p, generation, totalGenerations, start, midPoint);
                }

                // halve the distance the lightning can deviate for each generation down
                offsetAmount *= 0.5f;
            }
        }
Exemple #2
0
        public void GenerateLightningBolt(LightningBolt bolt, LightningBoltParameters p)
        {
            Vector3 start = p.ApplyVariance(p.Start, p.StartVariance);
            Vector3 end   = p.ApplyVariance(p.End, p.EndVariance);

            OnGenerateLightningBolt(bolt, start, end, p);
        }
Exemple #3
0
 public void CreateFork(LightningBolt bolt, LightningBoltParameters p, int generation, int totalGenerations, Vector3 start, Vector3 midPoint)
 {
     if (ShouldCreateFork(p, generation, totalGenerations))
     {
         Vector3 branchVector = (midPoint - start) * p.ForkMultiplier();
         Vector3 splitEnd     = midPoint + branchVector;
         GenerateLightningBoltStandard(bolt, midPoint, splitEnd, generation, totalGenerations, 0.0f, p);
     }
 }
Exemple #4
0
 /// <summary>
 /// Create multiple lightning bolts, attempting to batch them into as few draw calls as possible
 /// </summary>
 /// <param name="parameters">Lightning bolt creation parameters</param>
 public void CreateLightningBolts(ICollection <LightningBoltParameters> parameters)
 {
     if (parameters != null && parameters.Count != 0)
     {
         UpdateTexture();
         LightningBolt             bolt         = GetOrCreateLightningBolt();
         LightningBoltDependencies dependencies = CreateLightningBoltDependencies(parameters);
         bolt.SetupLightningBolt(dependencies);
     }
 }
Exemple #5
0
        public void GenerateLightningBolt(LightningBoltParameters p, LightningBolt bolt)
        {
            CurrentBolt = bolt;

            Vector3 start = p.ApplyVariance(p.Start, p.StartVariance);
            Vector3 end   = p.ApplyVariance(p.End, p.EndVariance);

            OnGenerateLightningBolt(start, end, p);

            CurrentBolt = null;
        }
Exemple #6
0
 /// <summary>
 /// Create a lightning bolt
 /// </summary>
 /// <param name="p">Lightning bolt creation parameters</param>
 public virtual void CreateLightningBolt(LightningBoltParameters p)
 {
     if (p != null)
     {
         UpdateTexture();
         oneParameterArray[0] = p;
         LightningBolt             bolt         = GetOrCreateLightningBolt();
         LightningBoltDependencies dependencies = CreateLightningBoltDependencies(oneParameterArray);
         bolt.SetupLightningBolt(dependencies);
     }
 }
Exemple #7
0
        public void RandomVector(LightningBolt bolt, ref Vector3 start, ref Vector3 end, float offsetAmount, System.Random random, out Vector3 result)
        {
            if (bolt.CameraMode == CameraMode.Perspective)
            {
                Vector3 direction = (end - start).normalized;
                Vector3 side      = Vector3.Cross(start, end);
                if (side == Vector3.zero)
                {
                    // slow path, rarely hit unless cross product is zero
                    GetPerpendicularVector(ref direction, out side);
                }
                else
                {
                    side.Normalize();
                }

                // generate random distance and angle
                float distance = (((float)random.NextDouble() + 0.1f) * offsetAmount);

#if DEBUG
                float rotationAngle = ((float)random.NextDouble() * 360.0f);
                result = Quaternion.AngleAxis(rotationAngle, direction) * side * distance;
#else
                // optimized path for RELEASE mode, skips two normalize and two multiplies in Quaternion.AngleAxis
                float rotationAngle = ((float)random.NextDouble() * Mathf.PI);
                direction *= (float)System.Math.Sin(rotationAngle);
                Quaternion rotation;
                rotation.x = direction.x;
                rotation.y = direction.y;
                rotation.z = direction.z;
                rotation.w = (float)System.Math.Cos(rotationAngle);
                result     = rotation * side * distance;
#endif
            }
            else if (bolt.CameraMode == CameraMode.OrthographicXY)
            {
                // XY plane
                end.z = start.z;
                Vector3 directionNormalized = (end - start).normalized;
                Vector3 side     = new Vector3(-directionNormalized.y, directionNormalized.x, 0.0f);
                float   distance = ((float)random.NextDouble() * offsetAmount * 2.0f) - offsetAmount;
                result = side * distance;
            }
            else
            {
                // XZ plane
                end.y = start.y;
                Vector3 directionNormalized = (end - start).normalized;
                Vector3 side     = new Vector3(-directionNormalized.z, 0.0f, directionNormalized.x);
                float   distance = ((float)random.NextDouble() * offsetAmount * 2.0f) - offsetAmount;
                result = side * distance;
            }
        }
Exemple #8
0
        internal void AddActiveBolt(LightningBolt bolt)
        {
#if DEBUG
            if (bolt == null || activeBolts.Contains(bolt))
            {
                Debug.LogError("Attempted to add null or duplicate active lightning bolt");
                return;
            }
#endif

            // only called from the main thread
            activeBolts.Add(bolt);
        }
Exemple #9
0
 private void UpdateActiveBolts()
 {
     for (int i = activeBolts.Count - 1; i >= 0; i--)
     {
         LightningBolt bolt = activeBolts[i];
         if (!bolt.Update())
         {
             // bolt is done, remove it and put back in cache
             activeBolts.RemoveAt(i);
             bolt.Cleanup();
             lightningBoltCache.Add(bolt);
         }
     }
 }
Exemple #10
0
        private LightningBolt GetOrCreateLightningBolt()
        {
            if (lightningBoltCache.Count == 0)
            {
#if ENABLE_PROFILING
                Debug.Log("Lightning cache miss");
#endif

                return(new LightningBolt());
            }
            LightningBolt b = lightningBoltCache[lightningBoltCache.Count - 1];
            lightningBoltCache.RemoveAt(lightningBoltCache.Count - 1);

            return(b);
        }
Exemple #11
0
        /// <summary>
        /// Create multiple lightning bolts, attempting to batch them into as few draw calls as possible
        /// </summary>
        /// <param name="parameters">Lightning bolt creation parameters</param>
        public void CreateLightningBolts(ICollection <LightningBoltParameters> parameters)
        {
#if UNITY_EDITOR
            if (Camera == null)
            {
                UnityEngine.Debug.LogError("Camera not assigned to lightning script. Either set the camera or tag your camera as main camera.");
            }
#endif

            if (parameters != null && parameters.Count != 0 && Camera != null)
            {
                UpdateTexture();
                LightningBolt             bolt         = GetOrCreateLightningBolt();
                LightningBoltDependencies dependencies = CreateLightningBoltDependencies(parameters);
                bolt.SetupLightningBolt(dependencies);
            }
        }
Exemple #12
0
        /// <summary>
        /// Create a lightning bolt
        /// </summary>
        /// <param name="p">Lightning bolt creation parameters</param>
        public virtual void CreateLightningBolt(LightningBoltParameters p)
        {
#if UNITY_EDITOR
            if (Camera == null)
            {
                UnityEngine.Debug.LogError("Camera not assigned to lightning script. Either set the camera or tag your camera as main camera.");
            }
#endif

            if (p != null && Camera != null)
            {
                UpdateTexture();
                oneParameterArray[0] = p;
                LightningBolt             bolt         = GetOrCreateLightningBolt();
                LightningBoltDependencies dependencies = CreateLightningBoltDependencies(oneParameterArray);
                bolt.SetupLightningBolt(dependencies);
            }
        }
Exemple #13
0
 private void OnSceneLoaded(UnityEngine.SceneManagement.Scene arg0, UnityEngine.SceneManagement.LoadSceneMode arg1)
 {
     LightningBolt.ClearCache();
 }
        private LineRendererMesh CreateLineRenderer(LightningBolt lightningBolt, List<LineRendererMesh> lineRenderers)
        {
            LineRendererMesh lineRenderer;

            if (rendererCache.Count == 0)
            {
                // create a line renderer in a new game object underneath the parent
                GameObject obj = new GameObject();
                obj.name = "LightningBoltMeshRenderer";
                obj.hideFlags = HideFlags.HideAndDontSave;
                lineRenderer = obj.AddComponent<LineRendererMesh>();
            }
            else
            {
                lineRenderer = rendererCache[rendererCache.Count - 1];
                rendererCache.RemoveAt(rendererCache.Count - 1);
            }

            // clear parent - this ensures that the rotation and scale can be reset before assigning a new parent
            lineRenderer.gameObject.transform.parent = null;
            lineRenderer.gameObject.transform.rotation = Quaternion.identity;
            lineRenderer.gameObject.transform.localScale = Vector3.one;
            lineRenderer.gameObject.transform.parent = lightningBolt.Parent.transform;
            lineRenderer.gameObject.layer = lightningBolt.Parent.layer; // maintain the layer of the parent

            if (lightningBolt.UseWorldSpace)
            {
                lineRenderer.gameObject.transform.position = Vector3.zero;
            }
            else
            {
                lineRenderer.gameObject.transform.localPosition = Vector3.zero;
            }

            lineRenderer.Material = (lightningBolt.HasGlow ? Material : MaterialNoGlow);
            lineRenderer.MeshRenderer.sortingLayerName = lightningBolt.SortLayerName;
            lineRenderer.MeshRenderer.sortingOrder = lightningBolt.SortOrderInLayer;
            currentLineRenderer = lineRenderer;
            lineRenderers.Add(lineRenderer);

            return lineRenderer;
        }
 public void Begin(LightningBolt lightningBolt)
 {
     List<LineRendererMesh> lineRenderers;
     if (!renderers.TryGetValue(lightningBolt, out lineRenderers))
     {
         lineRenderers = new List<LineRendererMesh>();
         renderers[lightningBolt] = lineRenderers;
         CreateLineRenderer(lightningBolt, lineRenderers);
     }
 }
 public void End(LightningBolt lightningBolt)
 {
     if (currentLineRenderer != null)
     {
         Script.StartCoroutine(EnableRenderer(currentLineRenderer, lightningBolt));
         currentLineRenderer = null;
     }
 }
 public void Cleanup(LightningBolt lightningBolt)
 {
     List<LineRendererMesh> lineRenderers;
     if (renderers.TryGetValue(lightningBolt, out lineRenderers))
     {
         renderers.Remove(lightningBolt);
         foreach (LineRendererMesh lineRenderer in lineRenderers)
         {
             rendererCache.Add(lineRenderer);
             lineRenderer.Reset();
         }
     }
 }
Exemple #18
0
 protected override void OnGenerateLightningBolt(LightningBolt bolt, Vector3 start, Vector3 end, LightningBoltParameters p)
 {
     GenerateLightningBoltPath(bolt, start, end, p);
 }
Exemple #19
0
        public void GenerateLightningBoltPath(LightningBolt bolt, Vector3 start, Vector3 end, LightningBoltParameters p)
        {
            if (p.Points.Count < 2)
            {
                Debug.LogError("Lightning path should have at least two points");
                return;
            }

            int     generation = p.Generations;
            int     totalGenerations = generation;
            float   offsetAmount, d;
            int     smoothingFactor = p.SmoothingFactor - 1;
            Vector3 distance, randomVector;
            LightningBoltSegmentGroup group = bolt.AddGroup();

            group.LineWidth          = p.TrunkWidth;
            group.Generation         = generation--;
            group.EndWidthMultiplier = p.EndWidthMultiplier;
            group.Color = Color.white;

            p.Start = p.Points[0] + start;
            p.End   = p.Points[p.Points.Count - 1] + end;
            end     = p.Start;

            for (int i = 1; i < p.Points.Count; i++)
            {
                start    = end;
                end      = p.Points[i];
                distance = (end - start);
                d        = PathGenerator.SquareRoot(distance.sqrMagnitude);
                if (p.ChaosFactor > 0.0f)
                {
                    if (bolt.CameraMode == CameraMode.Perspective)
                    {
                        end += (d * p.ChaosFactor * RandomDirection3D(p.Random));
                    }
                    else if (bolt.CameraMode == CameraMode.OrthographicXY)
                    {
                        end += (d * p.ChaosFactor * RandomDirection2D(p.Random));
                    }
                    else
                    {
                        end += (d * p.ChaosFactor * RandomDirection2DXZ(p.Random));
                    }
                    distance = (end - start);
                }
                group.Segments.Add(new LightningBoltSegment {
                    Start = start, End = end
                });

                offsetAmount = d * p.ChaosFactor;
                RandomVector(bolt, ref start, ref end, offsetAmount, p.Random, out randomVector);

                if (ShouldCreateFork(p, generation, totalGenerations))
                {
                    Vector3 branchVector = distance * p.ForkMultiplier() * smoothingFactor * 0.5f;
                    Vector3 forkEnd      = end + branchVector + randomVector;
                    GenerateLightningBoltStandard(bolt, start, forkEnd, generation, totalGenerations, 0.0f, p);
                }

                if (--smoothingFactor == 0)
                {
                    smoothingFactor = p.SmoothingFactor - 1;
                }
            }
        }
        private IEnumerator EnableRenderer(LineRendererMesh renderer, LightningBolt lightningBolt)
        {
            yield return new WaitForSeconds(lightningBolt.MinimumDelay);

            if (renderer != null && lightningBolt.IsActive)
            {
                renderer.Begin();
            }
        }
Exemple #21
0
        public void GenerateLightningBolt(LightningBolt bolt, LightningBoltParameters p)
        {
            Vector3 start, end;

            GenerateLightningBolt(bolt, p, out start, out end);
        }
Exemple #22
0
 protected virtual void OnGenerateLightningBolt(LightningBolt bolt, Vector3 start, Vector3 end, LightningBoltParameters p)
 {
     GenerateLightningBoltStandard(bolt, start, end, p.Generations, p.Generations, 0.0f, p);
 }
        public void AddGroup(LightningBolt lightningBolt, LightningBoltSegmentGroup group, float growthMultiplier)
        {
            if (group.SegmentCount == 0)
            {
                return;
            }

            List<LineRendererMesh> lineRenderers = renderers[lightningBolt];
            LineRendererMesh lineRenderer = lineRenderers[lineRenderers.Count - 1];
            float timeStart = Time.timeSinceLevelLoad + group.Delay;
            Vector4 fadeLifeTime = new Vector4(timeStart, timeStart + group.PeakStart, timeStart + group.PeakEnd, timeStart + group.LifeTime);
            float radius = group.LineWidth * 0.5f * LightningBoltParameters.Scale;
            int lineCount = (group.Segments.Count - group.StartIndex);
            float radiusStep = (radius - (radius * group.EndWidthMultiplier)) / (float)lineCount;

            // growth multiplier
            float timeStep, timeOffset;
            if (growthMultiplier > 0.0f)
            {
                timeStep = (group.LifeTime / (float)lineCount) * growthMultiplier;
                timeOffset = 0.0f;
            }
            else
            {
                timeStep = 0.0f;
                timeOffset = 0.0f;
            }

            if (!lineRenderer.PrepareForLines(lineCount))
            {
                Script.StartCoroutine(EnableRenderer(lineRenderer, lightningBolt));
                lineRenderer = CreateLineRenderer(lightningBolt, lineRenderers);
            }

            lineRenderer.BeginLine(group.Segments[group.StartIndex].Start, group.Segments[group.StartIndex].End, radius, group.Color, fadeLifeTime, GlowWidthMultiplier, GlowIntensityMultiplier);
            for (int i = group.StartIndex + 1; i < group.Segments.Count; i++)
            {
                radius -= radiusStep;
                if (growthMultiplier < 1.0f)
                {
                    timeOffset += timeStep;
                    fadeLifeTime = new Color(timeStart + timeOffset, timeStart + group.PeakStart + timeOffset, timeStart + group.PeakEnd, timeStart + group.LifeTime);
                }
                lineRenderer.AppendLine(group.Segments[i].Start, group.Segments[i].End, radius, group.Color, fadeLifeTime, GlowWidthMultiplier, GlowIntensityMultiplier);
            }
        }