private IEnumerator EnableLastRendererCoRoutine() { LineRendererMesh lineRenderer = activeLineRenderers[activeLineRenderers.Count - 1]; int tag = ++lineRenderer.Tag; // in case it gets cleaned up for later yield return(new WaitForSecondsLightning(MinimumDelay)); EnableLineRenderer(lineRenderer, tag); }
private void EnableLineRenderer(LineRendererMesh lineRenderer, int tag) { bool shouldPopulate = (lineRenderer != null && lineRenderer.GameObject != null && lineRenderer.Tag == tag && IsActive); if (shouldPopulate) { lineRenderer.PopulateMesh(); } }
private LineRendererMesh GetOrCreateLineRenderer() { LineRendererMesh lineRenderer; while (true) { if (lineRendererCache.Count == 0) { lineRenderer = new LineRendererMesh(); } else { int index = lineRendererCache.Count - 1; lineRenderer = lineRendererCache[index]; lineRendererCache.RemoveAt(index); if (lineRenderer == null || lineRenderer.Transform == null) { // destroyed by some other means, try again for cache... continue; } } break; } // clear parent - this ensures that the rotation and scale can be reset before assigning a new parent lineRenderer.Transform.parent = null; lineRenderer.Transform.rotation = Quaternion.identity; lineRenderer.Transform.localScale = Vector3.one; lineRenderer.Transform.parent = dependencies.Parent.transform; lineRenderer.GameObject.layer = dependencies.Parent.layer; // maintain the layer of the parent if (dependencies.UseWorldSpace) { lineRenderer.GameObject.transform.position = Vector3.zero; } else { lineRenderer.GameObject.transform.localPosition = Vector3.zero; } lineRenderer.Material = (HasGlow ? dependencies.LightningMaterialMesh : dependencies.LightningMaterialMeshNoGlow); if (!string.IsNullOrEmpty(dependencies.SortLayerName)) { lineRenderer.MeshRenderer.sortingLayerName = dependencies.SortLayerName; lineRenderer.MeshRenderer.sortingOrder = dependencies.SortOrderInLayer; } else { lineRenderer.MeshRenderer.sortingLayerName = null; lineRenderer.MeshRenderer.sortingOrder = 0; } activeLineRenderers.Add(lineRenderer); return(lineRenderer); }
private Transform RenderLightningBolt(LightningBoltQualitySetting quality, int generations, int startGroupIndex, int endGroupIndex, LightningBoltParameters parameters) { if (segmentGroups.Count == 0 || startGroupIndex >= segmentGroups.Count || endGroupIndex > segmentGroups.Count) { return(null); } Transform transform = null; LightningLightParameters lp = parameters.LightParameters; if (lp != null) { if ((hasLight |= lp.HasLight)) { lp.LightPercent = Mathf.Clamp(lp.LightPercent, Mathf.Epsilon, 1.0f); lp.LightShadowPercent = Mathf.Clamp(lp.LightShadowPercent, 0.0f, 1.0f); } else { lp = null; } } LightningBoltSegmentGroup mainTrunkGroup = segmentGroups[startGroupIndex]; Vector3 start = mainTrunkGroup.Segments[mainTrunkGroup.StartIndex].Start; Vector3 end = mainTrunkGroup.Segments[mainTrunkGroup.StartIndex + mainTrunkGroup.SegmentCount - 1].End; parameters.FadePercent = Mathf.Clamp(parameters.FadePercent, 0.0f, 0.5f); // create a new line renderer mesh right now if we have a custom transform if (parameters.CustomTransform != null) { LineRendererMesh currentLineRenderer = (activeLineRenderers.Count == 0 || !activeLineRenderers[activeLineRenderers.Count - 1].Empty ? null : activeLineRenderers[activeLineRenderers.Count - 1]); if (currentLineRenderer == null) { #if !UNITY_WEBGL if (dependencies.ThreadState != null) { // we need to block until this action is run, Unity objects can only be modified and created on the main thread dependencies.ThreadState.AddActionForMainThread(() => { EnableCurrentLineRenderer(); currentLineRenderer = GetOrCreateLineRenderer(); }, true); } else #endif { EnableCurrentLineRenderer(); currentLineRenderer = GetOrCreateLineRenderer(); } } if (currentLineRenderer == null) { return(null); } currentLineRenderer.CustomTransform = parameters.CustomTransform; transform = currentLineRenderer.Transform; } for (int i = startGroupIndex; i < endGroupIndex; i++) { LightningBoltSegmentGroup group = segmentGroups[i]; group.Delay = parameters.delaySeconds; group.LifeTime = parameters.LifeTime; group.PeakStart = group.LifeTime * parameters.FadePercent; group.PeakEnd = group.LifeTime - group.PeakStart; float peakGap = group.PeakEnd - group.PeakStart; float fadeOut = group.LifeTime - group.PeakEnd; group.PeakStart *= parameters.FadeInMultiplier; group.PeakEnd = group.PeakStart + (peakGap * parameters.FadeFullyLitMultiplier); group.LifeTime = group.PeakEnd + (fadeOut * parameters.FadeOutMultiplier); group.LightParameters = lp; RenderGroup(group, parameters); } #if !UNITY_WEBGL if (dependencies.ThreadState != null) { dependencies.ThreadState.AddActionForMainThread(() => { RenderParticleSystems(start, end, parameters.TrunkWidth, parameters.LifeTime, parameters.delaySeconds); // create lights only on the main trunk if (lp != null) { CreateLightsForGroup(segmentGroups[startGroupIndex], lp, quality, parameters.maxLights); } }); } else #endif { RenderParticleSystems(start, end, parameters.TrunkWidth, parameters.LifeTime, parameters.delaySeconds); // create lights only on the main trunk if (lp != null) { CreateLightsForGroup(segmentGroups[startGroupIndex], lp, quality, parameters.maxLights); } } return(transform); }
private void RenderGroup(LightningBoltSegmentGroup group, LightningBoltParameters p) { if (group.SegmentCount == 0) { return; } #if UNITY_WEBGL float timeOffset = 0.0f; #else float timeOffset = (dependencies.ThreadState == null ? 0.0f : (float)(DateTime.UtcNow - startTimeOffset).TotalSeconds); #endif float timeStart = timeSinceLevelLoad + group.Delay + timeOffset; 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; if (p.GrowthMultiplier > 0.0f) { timeStep = (group.LifeTime / (float)lineCount) * p.GrowthMultiplier; timeOffset = 0.0f; } else { timeStep = 0.0f; timeOffset = 0.0f; } LineRendererMesh currentLineRenderer = (activeLineRenderers.Count == 0 ? GetOrCreateLineRenderer() : activeLineRenderers[activeLineRenderers.Count - 1]); // if we have filled up the mesh, we need to start a new line renderer if (!currentLineRenderer.PrepareForLines(lineCount)) { if (currentLineRenderer.CustomTransform != null) { // can't create multiple meshes if using a custom transform callback return; } #if !UNITY_WEBGL if (dependencies.ThreadState != null) { // we need to block until this action is run, Unity objects can only be modified and created on the main thread dependencies.ThreadState.AddActionForMainThread(() => { EnableCurrentLineRenderer(); currentLineRenderer = GetOrCreateLineRenderer(); }, true); } else #endif { EnableCurrentLineRenderer(); currentLineRenderer = GetOrCreateLineRenderer(); } } currentLineRenderer.BeginLine(group.Segments[group.StartIndex].Start, group.Segments[group.StartIndex].End, radius, group.Color, p.Intensity, fadeLifeTime, p.GlowWidthMultiplier, p.GlowIntensity); for (int i = group.StartIndex + 1; i < group.Segments.Count; i++) { radius -= radiusStep; if (p.GrowthMultiplier < 1.0f) { timeOffset += timeStep; fadeLifeTime = new Vector4(timeStart + timeOffset, timeStart + group.PeakStart + timeOffset, timeStart + group.PeakEnd, timeStart + group.LifeTime); } currentLineRenderer.AppendLine(group.Segments[i].Start, group.Segments[i].End, radius, group.Color, p.Intensity, fadeLifeTime, p.GlowWidthMultiplier, p.GlowIntensity); } }
public void End(LightningBolt lightningBolt) { if (currentLineRenderer != null) { Script.StartCoroutine(EnableRenderer(currentLineRenderer, lightningBolt)); currentLineRenderer = null; } }
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; }
private IEnumerator EnableRenderer(LineRendererMesh renderer, LightningBolt lightningBolt) { yield return new WaitForSeconds(lightningBolt.MinimumDelay); if (renderer != null && lightningBolt.IsActive) { renderer.Begin(); } }