예제 #1
0
        private void ProcessParameters(LightningBoltParameters p, RangeOfFloats delay, LightningBoltDependencies depends)
        {
            Vector3 start, end;

            MinimumDelay   = Mathf.Min(delay.Minimum, MinimumDelay);
            p.delaySeconds = delay.Random(p.Random);

            // apply LOD if specified
            if (depends.LevelOfDetailDistance > Mathf.Epsilon)
            {
                float d;
                if (p.Points.Count > 1)
                {
                    d = Vector3.Distance(depends.CameraPos, p.Points[0]);
                    d = Mathf.Min(Vector3.Distance(depends.CameraPos, p.Points[p.Points.Count - 1]));
                }
                else
                {
                    d = Vector3.Distance(depends.CameraPos, p.Start);
                    d = Mathf.Min(Vector3.Distance(depends.CameraPos, p.End));
                }
                int modifier = Mathf.Min(8, (int)(d / depends.LevelOfDetailDistance));
                p.Generations = Mathf.Max(1, p.Generations - modifier);
                p.GenerationWhereForksStopSubtractor = Mathf.Clamp(p.GenerationWhereForksStopSubtractor - modifier, 0, 8);
            }

            p.generationWhereForksStop = p.Generations - p.GenerationWhereForksStopSubtractor;
            lifeTime               = Mathf.Max(p.LifeTime + p.delaySeconds, lifeTime);
            maxLifeTime            = Mathf.Max(lifeTime, maxLifeTime);
            p.forkednessCalculated = (int)Mathf.Ceil(p.Forkedness * (float)p.Generations);
            if (p.Generations > 0)
            {
                p.Generator = p.Generator ?? LightningGenerator.GeneratorInstance;
                p.Generator.GenerateLightningBolt(this, p, out start, out end);
                p.Start = start;
                p.End   = end;
            }
        }
        private static void UpdateTransform(LightningCustomTransformStateInfo state, LightningBoltPrefabScript script, RangeOfFloats scaleLimit)
        {
            if (state.Transform == null || state.StartTransform == null)
            {
                return;
            }
            else if (state.EndTransform == null)
            {
                // just put the lightning at the start and be done
                state.Transform.position = state.StartTransform.position - state.BoltStartPosition;
                return;
            }

            Quaternion rotation;

            if ((script.CameraMode == CameraMode.Auto && script.Camera.orthographic) ||
                (script.CameraMode == CameraMode.OrthographicXY))
            {
                // 2D rotation delta (xy)
                float startAngle   = AngleBetweenVector2(state.BoltStartPosition, state.BoltEndPosition);
                float currentAngle = AngleBetweenVector2(state.StartTransform.position, state.EndTransform.position);
                rotation = Quaternion.AngleAxis((currentAngle - startAngle), Vector3.forward);
            }
            if (script.CameraMode == CameraMode.OrthographicXZ)
            {
                // 2D rotation delta (xz)
                float startAngle   = AngleBetweenVector2(new Vector2(state.BoltStartPosition.x, state.BoltStartPosition.z), new Vector2(state.BoltEndPosition.x, state.BoltEndPosition.z));
                float currentAngle = AngleBetweenVector2(new Vector2(state.StartTransform.position.x, state.StartTransform.position.z), new Vector2(state.EndTransform.position.x, state.EndTransform.position.z));
                rotation = Quaternion.AngleAxis((currentAngle - startAngle), Vector3.up);
            }
            else
            {
                // 3D rotation delta
                Quaternion look1 = Quaternion.LookRotation((state.BoltEndPosition - state.BoltStartPosition).normalized);
                Quaternion look2 = Quaternion.LookRotation((state.EndTransform.position - state.StartTransform.position).normalized);
                rotation = look2 * Quaternion.Inverse(look1);
            }
            state.Transform.rotation = rotation;

            // scale based on how much the objects have moved relative to each other
            float startDistance = Vector3.Distance(state.BoltStartPosition, state.BoltEndPosition);
            float endDistance   = Vector3.Distance(state.EndTransform.position, state.StartTransform.position);
            float scale         = Mathf.Clamp((startDistance < Mathf.Epsilon ? 1.0f : endDistance / startDistance), scaleLimit.Minimum, scaleLimit.Maximum);

            state.Transform.localScale = new Vector3(scale, scale, scale);

            // anchor lightning to start position and account for rotation and scale
            Vector3 offset = rotation * (scale * state.BoltStartPosition);

            state.Transform.position = state.StartTransform.position - offset;
        }
            private void Strike(Vector3?_start, Vector3?_end, bool intense, float intensity, Camera camera, Camera visibleInCamera)
            {
                // find a point around the camera that is not too close
                const float minDistance  = 500.0f;
                float       minValue     = (intense ? -1000.0f : -5000.0f);
                float       maxValue     = (intense ? 1000 : 5000.0f);
                float       closestValue = (intense ? 500.0f : 2500.0f);
                float       x            = (UnityEngine.Random.Range(0, 2) == 0 ? UnityEngine.Random.Range(minValue, -closestValue) : UnityEngine.Random.Range(closestValue, maxValue));
                float       y            = script.LightningYStart;
                float       z            = (UnityEngine.Random.Range(0, 2) == 0 ? UnityEngine.Random.Range(minValue, -closestValue) : UnityEngine.Random.Range(closestValue, maxValue));
                Vector3     start        = script.Camera.transform.position;

                start.x += x;
                start.y  = y;
                start.z += z;

                if (visibleInCamera != null)
                {
                    // try and make sure the strike is visible in the camera
                    Quaternion q = visibleInCamera.transform.rotation;
                    visibleInCamera.transform.rotation = Quaternion.Euler(0.0f, q.eulerAngles.y, 0.0f);
                    float   screenX = UnityEngine.Random.Range(visibleInCamera.pixelWidth * 0.1f, visibleInCamera.pixelWidth * 0.9f);
                    float   ScreenZ = UnityEngine.Random.Range(visibleInCamera.nearClipPlane + closestValue + closestValue, maxValue);
                    Vector3 point   = visibleInCamera.ScreenToWorldPoint(new Vector3(screenX, 0.0f, ScreenZ));
                    start   = point;
                    start.y = y;
                    visibleInCamera.transform.rotation = q;
                }

                Vector3 end = start;

                x = UnityEngine.Random.Range(-100, 100.0f);

                // 1 in 4 chance not to strike the ground
                y = (UnityEngine.Random.Range(0, 4) == 0 ? UnityEngine.Random.Range(-1, 600.0f) : -1.0f);

                z += UnityEngine.Random.Range(-100.0f, 100.0f);

                end.x += x;
                end.y  = y;
                end.z += z;

                // make sure the bolt points away from the camera
                end.x += (closestValue * camera.transform.forward.x);
                end.z += (closestValue * camera.transform.forward.z);

                while ((start - end).magnitude < minDistance)
                {
                    end.x += (closestValue * camera.transform.forward.x);
                    end.z += (closestValue * camera.transform.forward.z);
                }

                start = (_start ?? start);
                end   = (_end ?? end);

                // see if the bolt hit anything on it's way to the ground - if so, change the end point
                RaycastHit hit;

                if (Physics.Raycast(start, (start - end).normalized, out hit, float.MaxValue))
                {
                    end = hit.point;
                }

                int           generations = script.LightningBoltScript.Generations;
                RangeOfFloats trunkWidth  = script.LightningBoltScript.TrunkWidthRange;

                if (UnityEngine.Random.value < script.CloudLightningChance)
                {
                    // cloud only lightning
                    script.LightningBoltScript.TrunkWidthRange = new RangeOfFloats();
                    script.LightningBoltScript.Generations     = 1;
                }
                script.LightningBoltScript.LightParameters.LightIntensity = intensity * 0.5f;
                script.LightningBoltScript.Trigger(start, end);
                script.LightningBoltScript.TrunkWidthRange = trunkWidth;
                script.LightningBoltScript.Generations     = generations;
            }
예제 #4
0
        private void ProcessAllLightningParameters()
        {
            int           maxLightsForEachParameters = MaximumLightsPerBatch / dependencies.Parameters.Count;
            RangeOfFloats delay        = new RangeOfFloats();
            List <int>    groupIndexes = new List <int>(dependencies.Parameters.Count + 1);
            int           i            = 0;

#if ENABLE_PROFILING
            System.Diagnostics.Stopwatch w = System.Diagnostics.Stopwatch.StartNew();
#endif

            foreach (LightningBoltParameters parameters in dependencies.Parameters)
            {
                delay.Minimum        = parameters.DelayRange.Minimum + parameters.Delay;
                delay.Maximum        = parameters.DelayRange.Maximum + parameters.Delay;
                parameters.maxLights = maxLightsForEachParameters;
                groupIndexes.Add(segmentGroups.Count);
                ProcessParameters(parameters, delay, dependencies);
            }
            groupIndexes.Add(segmentGroups.Count);

#if ENABLE_PROFILING
            w.Stop();
            UnityEngine.Debug.LogFormat("GENERATE: {0}", w.Elapsed.TotalMilliseconds);
            w.Reset();
            w.Start();
#endif

            LightningBoltDependencies dependenciesRef = dependencies;
            foreach (LightningBoltParameters parameters in dependenciesRef.Parameters)
            {
                Transform transform = RenderLightningBolt(parameters.quality, parameters.Generations, groupIndexes[i], groupIndexes[++i], parameters);

#if !UNITY_WEBGL
                if (dependenciesRef.ThreadState != null)
                {
                    dependenciesRef.ThreadState.AddActionForMainThread(() =>
                    {
                        dependenciesRef.StartCoroutine(NotifyBolt(dependenciesRef, parameters, transform, parameters.Start, parameters.End));
                    });
                }
                else
#endif

                {
                    dependenciesRef.StartCoroutine(NotifyBolt(dependenciesRef, parameters, transform, parameters.Start, parameters.End));
                }
            }

#if ENABLE_PROFILING
            w.Stop();
            UnityEngine.Debug.LogFormat("RENDER: {0}", w.Elapsed.TotalMilliseconds);
#endif

#if !UNITY_WEBGL
            if (dependencies.ThreadState != null)
            {
                dependencies.ThreadState.AddActionForMainThread(EnableCurrentLineRendererFromThread);
            }
            else
#endif

            {
                EnableCurrentLineRenderer();
                dependencies.AddActiveBolt(this);
            }
        }