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 CreateLightsForGroup(LightningBoltSegmentGroup group, LightningLightParameters lp, LightningBoltQualitySetting quality, int maxLights, int groupIndex) { if (lightCount == MaximumLightCount || maxLights <= 0) { return; } segmentGroupsWithLight.Add(group); int segmentCount = group.SegmentCount; float lightPercent, lightShadowPercent; if (quality == LightningBoltQualitySetting.LimitToQualitySetting) { int level = QualitySettings.GetQualityLevel(); LightningQualityMaximum maximum; if (LightningBoltParameters.QualityMaximums.TryGetValue(level, out maximum)) { lightPercent = Mathf.Min(lp.LightPercent, maximum.MaximumLightPercent); lightShadowPercent = Mathf.Min(lp.LightShadowPercent, maximum.MaximumShadowPercent); } else { Debug.LogError("Unable to read lightning quality for level " + level.ToString()); lightPercent = lp.LightPercent; lightShadowPercent = lp.LightShadowPercent; } } else { lightPercent = lp.LightPercent; lightShadowPercent = lp.LightShadowPercent; } maxLights = Mathf.Max(1, Mathf.Min(maxLights, (int)(segmentCount * lightPercent))); int nthLight = Mathf.Max(1, (int)((segmentCount / maxLights))); int nthShadows = maxLights - (int)((float)maxLights * lightShadowPercent); int nthShadowCounter = nthShadows; // add lights evenly spaced for (int i = group.StartIndex + (int)(nthLight * 0.5f); i < group.Segments.Count; i += nthLight) { if (AddLightToGroup(group, lp, i, nthLight, nthShadows, ref maxLights, ref nthShadowCounter)) { return; } } // Debug.Log("Lightning light count: " + lightCount.ToString()); }
private void CreateLightsForGroup(LightningBoltSegmentGroup group, LightningLightParameters lp, LightningBoltQualitySetting quality, int maxLights) { if (lightCount == MaximumLightCount || maxLights <= 0) { return; } float fadeOutTime = (lifeTime - group.PeakEnd) * lp.FadeOutMultiplier; float peakGap = (group.PeakEnd - group.PeakStart) * lp.FadeFullyLitMultiplier; float peakStart = group.PeakStart * lp.FadeInMultiplier; float peakEnd = peakStart + peakGap; float maxLifeWithLights = peakEnd + fadeOutTime; maxLifeTime = Mathf.Max(maxLifeTime, group.Delay + maxLifeWithLights); segmentGroupsWithLight.Add(group); int segmentCount = group.SegmentCount; float lightPercent, lightShadowPercent; if (quality == LightningBoltQualitySetting.LimitToQualitySetting) { int level = QualitySettings.GetQualityLevel(); LightningQualityMaximum maximum; if (LightningBoltParameters.QualityMaximums.TryGetValue(level, out maximum)) { lightPercent = Mathf.Min(lp.LightPercent, maximum.MaximumLightPercent); lightShadowPercent = Mathf.Min(lp.LightShadowPercent, maximum.MaximumShadowPercent); } else { Debug.LogError("Unable to read lightning quality for level " + level.ToString()); lightPercent = lp.LightPercent; lightShadowPercent = lp.LightShadowPercent; } } else { lightPercent = lp.LightPercent; lightShadowPercent = lp.LightShadowPercent; } maxLights = Mathf.Max(1, Mathf.Min(maxLights, (int)(segmentCount * lightPercent))); int nthLight = Mathf.Max(1, (int)((segmentCount / maxLights))); int nthShadows = maxLights - (int)((float)maxLights * lightShadowPercent); int nthShadowCounter = nthShadows; // add lights evenly spaced for (int i = group.StartIndex + (int)(nthLight * 0.5f); i < group.Segments.Count; i += nthLight) { if (AddLightToGroup(group, lp, i, nthLight, nthShadows, ref maxLights, ref nthShadowCounter)) { return; } } // Debug.Log("Lightning light count: " + lightCount.ToString()); }
private void RenderLightningBolt(LightningBoltQualitySetting quality, int generations, Vector3 start, Vector3 end, int groupIndex, ParticleSystem originParticleSystem, ParticleSystem destParticleSystem, LightningBoltParameters parameters, LightningLightParameters lp, int maxLights) { if (parameters.Generations < 1) { CreateLightOnly(parameters, lp, start); return; } else if (segmentGroups.Count == 0 || groupIndex >= segmentGroups.Count) { return; } float delayBase = parameters.LifeTime / (float)segmentGroups.Count; float minDelayValue = delayBase * 0.9f; float maxDelayValue = delayBase * 1.1f; float delayDiff = maxDelayValue - minDelayValue; parameters.FadePercent = Mathf.Clamp(parameters.FadePercent, 0.0f, 0.5f); if (originParticleSystem != null) { // we have a strike, create a particle where the lightning is coming from Script.StartCoroutine(GenerateParticle(originParticleSystem, start, parameters.Delay)); } if (destParticleSystem != null) { Script.StartCoroutine(GenerateParticle(destParticleSystem, end, parameters.Delay * 1.1f)); } if (HasGlow) { lightningBoltRenderer.GlowIntensityMultiplier = parameters.GlowIntensity; lightningBoltRenderer.GlowWidthMultiplier = parameters.GlowWidthMultiplier; } float currentDelayAmount = 0.0f; for (int i = groupIndex; i < segmentGroups.Count; i++) { LightningBoltSegmentGroup group = segmentGroups[i]; group.Delay = currentDelayAmount + parameters.Delay; group.LifeTime = parameters.LifeTime - currentDelayAmount; group.PeakStart = group.LifeTime * parameters.FadePercent; group.PeakEnd = group.LifeTime - group.PeakStart; group.LightParameters = lp; lightningBoltRenderer.AddGroup(this, group, parameters.GrowthMultiplier); currentDelayAmount += ((float)parameters.Random.NextDouble() * minDelayValue) + delayDiff; // create lights only on the main trunk if (lp != null && group.Generation == generations) { CreateLightsForGroup(group, lp, quality, maxLights, groupIndex); } } }