Пример #1
0
 internal void MigrateOldCustompath(LevelSegmentCustomPath old)
 {
     segment     = old.segment;
     transform   = old.transform;
     spline      = old.spline;
     localPoints = old.localPoints;
 }
Пример #2
0
 protected virtual void OnEnteredSegment(LevelSegment entered)
 {
     if (isPlayerInstance)
     {
         entered.Enter();
     }
 }
Пример #3
0
        public LevelSegment Instantiate()
        {
            GameObject   go  = Object.Instantiate(_prefab);
            LevelSegment seg = go.GetComponent <LevelSegment>();

            return(seg);
        }
Пример #4
0
 IEnumerator ClearRoutine()
 {
     _ready = false;
     if (usePathGeneratorInstance && overridePathGenerator != null)
     {
         Destroy(overridePathGenerator);
     }
     overridePathGenerator = null;
     while (isLoadingLevel)
     {
         yield return(null);
     }
     LevelSegment.ResetGenerationState();
     SegmentExtruder.instance.Stop();
     for (int i = 0; i < levels.Length; i++)
     {
         if (levels[i].remoteSequence && levels[i].isReady)
         {
             yield return(StartCoroutine(UnloadRemoteLevel(levels[i], ThreadPriority.High)));
         }
     }
     for (int i = 0; i < _segments.Count; i++)
     {
         _segments[i].DestroyImmediate();
     }
     ResourceManagement.UnloadResources();
     _segments.Clear();
     enteredLevel    = null;
     _enteredSegment = -1;
 }
Пример #5
0
        public static void DrawBounds(LevelSegment segment)
        {
            if (segment.alwaysDraw)
            {
                return;
            }
            TS_Bounds bound = segment.GetBounds();
            Transform trs   = segment.transform;
            Vector3   a     = trs.TransformPoint(bound.min);
            Vector3   b     = trs.TransformPoint(new Vector3(bound.max.x, bound.min.y, bound.min.z));
            Vector3   c     = trs.TransformPoint(new Vector3(bound.max.x, bound.min.y, bound.max.z));
            Vector3   d     = trs.TransformPoint(new Vector3(bound.min.x, bound.min.y, bound.max.z));

            Vector3 e = trs.TransformPoint(new Vector3(bound.min.x, bound.max.y, bound.min.z));
            Vector3 f = trs.TransformPoint(new Vector3(bound.max.x, bound.max.y, bound.min.z));
            Vector3 g = trs.TransformPoint(new Vector3(bound.max.x, bound.max.y, bound.max.z));
            Vector3 h = trs.TransformPoint(new Vector3(bound.min.x, bound.max.y, bound.max.z));

            Handles.color = Color.green;
            Handles.DrawLine(a, b);
            Handles.DrawLine(b, c);
            Handles.DrawLine(c, d);
            Handles.DrawLine(d, a);

            Handles.DrawLine(e, f);
            Handles.DrawLine(f, g);
            Handles.DrawLine(g, h);
            Handles.DrawLine(h, e);

            Handles.DrawLine(a, e);
            Handles.DrawLine(b, f);
            Handles.DrawLine(c, g);
            Handles.DrawLine(d, h);
        }
Пример #6
0
        private void DoUpdate()
        {
            if (LevelGenerator.instance == null || !LevelGenerator.instance.ready)
            {
                _result.position = trs.position;
                _result.up       = trs.up;
                _result.forward  = trs.forward;
                _result.percent  = 0.0;
                return;
            }
            if (Time.unscaledTime - lastUpdateTime < updateTime)
            {
                return;
            }
            LevelGenerator.instance.Project(trs.position, _result, useAccurateMode);
            int index = 0;

            LevelGenerator.instance.GlobalToLocalPercent(_result.percent, out index);
            _segmentIndex = index;
            _levelSegment = LevelGenerator.instance.segments[_segmentIndex];
            if (onProject != null)
            {
                onProject();
            }
            if (_levelSegment != lastSegment)
            {
                _levelSegment.Enter();
                lastSegment = _levelSegment;
            }
            lastUpdateTime = Time.unscaledTime;
        }
Пример #7
0
 public virtual void Continue(LevelSegment segment)
 {
     level        = segment.level;
     this.segment = segment;
     lastPoint    = segment.path.spline.points[segment.path.spline.points.Length - 1];
     InverseTransformPoint(ref lastPoint);
     FloatingOrigin.onOriginOffset -= OnOriginOffset;
     FloatingOrigin.onOriginOffset += OnOriginOffset;
 }
Пример #8
0
 public virtual void StartFollow(LevelSegment segment, double percent)
 {
     if (LevelGenerator.instance == null || !LevelGenerator.instance.ready || LevelGenerator.instance.segments.Count == 0)
     {
         Debug.LogError(name + " Runner attempting to start following but the Level Generator isn't ready.");
         return;
     }
     Init(segment, percent);
     follow = true;
 }
Пример #9
0
 public void Stop()
 {
     if (buildThread != null && buildThread.IsAlive)
     {
         buildThread.Abort();
     }
     buildQueue.Clear();
     buildSegment = null;
     postBuild    = false;
 }
Пример #10
0
 /// <summary>
 /// Logic for restarting the generation - usually called when the level generator restarts
 /// </summary>
 public virtual void Initialize(LevelGenerator input)
 {
     level       = null;
     segment     = null;
     _isNewLevel = false;
     transform   = input.transform;
     lastPoint   = new SplinePoint(Vector3.zero, Vector3.forward, Vector3.up, 1f, Color.white);
     FloatingOrigin.onOriginOffset -= OnOriginOffset;
     FloatingOrigin.onOriginOffset += OnOriginOffset;
 }
Пример #11
0
        // Update is called once per frame
        void Update()
        {
            if (multithreaded)
            {
                bool startThread = buildThread == null;
                if (!startThread)
                {
                    startThread = !buildThread.IsAlive;
                }
                if (startThread)
                {
                    if (buildThread != null)
                    {
                        Debug.Log("Thread restarted");
                    }
                    buildThread = new Thread(BuildThread);
                    buildThread.Start();
                }
            }

            if (postBuild)
            {
                buildSegment.OnPostExtrude();
                buildSegment = null;
                postBuild    = false;
                framesPassed = 0;
            }


            if (buildSegment == null && framesPassed >= framesBetweenBuilds)
            {
                if (buildQueue.Count > 0)
                {
                    if (LevelSegment.generationState == LevelSegment.GenerationState.Free || LevelSegment.generationState == LevelSegment.GenerationState.Idle)
                    {
                        buildSegment = buildQueue[0];
                        buildSegment.OnBeforeExtrude();
                        buildQueue.RemoveAt(0);
                        if (multithreaded)
                        {
                            buildThread.Interrupt();
                        }
                        else if (buildSegment != null)
                        {
                            buildSegment.Extrude();
                            postBuild = true;
                        }
                    }
                }
            }
            if (framesPassed < framesBetweenBuilds)
            {
                framesPassed++;
            }
        }
Пример #12
0
        IEnumerator StartRoutine()
        {
            _ready = false;
            _generationProgress = 0f;
            while (isLoadingLevel && !testMode)
            {
                yield return(null);
            }
            LevelSegment.ResetGenerationState();
            int count = 0;

            if (type == Type.Finite)
            {
                count = finiteSegmentsCount;
            }
            else
            {
                count = 1 + generateSegmentsAhead;
            }
            StartCoroutine(ProgressRoutine(count));
            for (int i = 0; i < count; i++)
            {
                CreateNextSegment();
                yield return(new WaitForSeconds(0.1f));
            }
            for (int i = 0; i < _segments.Count; i++)
            {
                while (_segments.Count > i && !_segments[i].extruded && _segments[i].type == LevelSegment.Type.Extruded)
                {
                    yield return(null);
                }
                if (type == Type.Finite)
                {
                    _segments[i].Activate();
                }
            }
            if (type == Type.Finite)
            {
                if (finiteLoop)
                {
                    _segments[_segments.Count - 1].next = _segments[0];
                    _segments[0].previous = _segments[_segments.Count - 1];
                }
            }
            _segments[0].Enter();
            while (LevelSegment.generationState != LevelSegment.GenerationState.Idle)
            {
                yield return(null);
            }
            _ready = true;
            if (onReady != null)
            {
                onReady();
            }
        }
Пример #13
0
 /// <summary>
 /// Logic for transfering internal data from the previous generator to the new one
 /// when changing path generators on-the-fly at runtime
 /// </summary>
 /// <param name="previousGenerator"></param>
 public virtual void Continue(LevelPathGenerator previousGenerator)
 {
     level       = previousGenerator.level;
     segment     = previousGenerator.segment;
     _isNewLevel = previousGenerator._isNewLevel;
     transform   = previousGenerator.transform;
     lastPoint   = previousGenerator.lastPoint;
     FloatingOrigin.onOriginOffset -= previousGenerator.OnOriginOffset;
     FloatingOrigin.onOriginOffset -= OnOriginOffset;
     FloatingOrigin.onOriginOffset += OnOriginOffset;
 }
Пример #14
0
 private void Init(LevelSegment input, double percentAlong = 0.0)
 {
     _segment = input;
     Evaluate(percentAlong, _result);
     if (isPlayerInstance)
     {
         _segment.Enter();
     }
     OnEnteredSegment(_segment);
     RefreshTargets();
 }
Пример #15
0
 protected override void OnEnteredSegment(LevelSegment entered)
 {
     base.OnEnteredSegment(entered);
     if (_lane >= _segment.customPaths.Length)
     {
         _lane = _segment.customPaths.Length;
     }
     if (_lastLane >= _segment.customPaths.Length)
     {
         _lastLane = _segment.customPaths.Length;
     }
 }
Пример #16
0
        public override void Continue(LevelSegment segment)
        {
            base.Continue(segment);
            SplineSample sample = new SplineSample();

            segment.Evaluate(1.0, sample);
            SplinePoint lastPoint = segment.path.spline.points[segment.path.spline.points.Length - 1];

            lastPointHL.position = transform.InverseTransformPoint(lastPoint.position);
            lastPointHL.rotation = (Quaternion.Inverse(transform.rotation) * sample.rotation).eulerAngles;
            lastPointHL.size     = sample.size;
            lastPointHL.color    = sample.color;
        }
Пример #17
0
 public static void DrawCustomPaths(LevelSegment segment)
 {
     if (segment.alwaysDraw)
     {
         return;
     }
     for (int i = 0; i < segment.customPaths.Length; i++)
     {
         Color col = segment.customPaths[i].color;
         col.a *= 0.5f;
         segment.customPaths[i].Transform();
         ForeverSplineDrawer.DrawSpline(segment.customPaths[i].spline, col);
     }
 }
Пример #18
0
 public static void DrawGeneratedSamples(LevelSegment segment)
 {
     //Debug spline samples
     for (int i = 0; i < segment.path.samples.Length; i++)
     {
         Vector3 pos    = segment.path.samples[i].position;
         Vector3 right  = segment.path.samples[i].right;
         Vector3 normal = segment.path.samples[i].up;
         float   size   = segment.path.samples[i].size;
         Handles.DrawLine(pos - right * segment.drawSampleScale * 0.5f * size, pos + right * segment.drawSampleScale * 0.5f * size);
         Handles.DrawLine(pos, pos + normal * segment.drawSampleScale * 0.5f);
     }
     Handles.color = Color.white;
 }
Пример #19
0
        private void OnSegmentEntered(LevelSegment entered)
        {
            _enteredSegment = entered.index;
            if (enteredLevel != entered.level)
            {
                enteredLevel = entered.level;
                int enteredIndex = 0;
                for (int i = 0; i < levels.Length; i++)
                {
                    if (enteredLevel == levels[i])
                    {
                        enteredIndex = i;
                        break;
                    }
                }
                if (onLevelEntered != null)
                {
                    onLevelEntered(enteredLevel, enteredIndex);
                }
            }

            for (int i = 0; i < _segments.Count; i++)
            {
                if (_segments[i] == entered)
                {
                    if (type == Type.Infinite)
                    {
                        int segmentsAhead = _segments.Count - (i + 1);
                        if (segmentsAhead < generateSegmentsAhead)
                        {
                            for (int j = segmentsAhead; j < generateSegmentsAhead; j++)
                            {
                                CreateNextSegment();
                            }
                        }
                        //Segment activation
                        for (int j = i; j <= i + activateSegmentsAhead && j < _segments.Count; j++)
                        {
                            if (!segments[j].activated)
                            {
                                _segments[j].Activate();
                            }
                        }
                    }
                    break;
                }
            }
        }
Пример #20
0
 public void StartBuild(LevelSegment segment)
 {
     if (_isDone)
     {
         return;
     }
     if (_isBuilding)
     {
         return;
     }
     if (buildQueued)
     {
         return;
     }
     levelSegment = segment;
     buildQueued  = true;
     Build();
     StartCoroutine(BuildRoutine());
 }
Пример #21
0
        protected void Traverse(SplineSample input)
        {
            float absFollowSpeed = followSpeed;

            Spline.Direction direction = Spline.Direction.Forward;
            if (absFollowSpeed < 0f)
            {
                absFollowSpeed *= -1f;
                direction       = Spline.Direction.Backward;
            }
            float travelDistance = Time.deltaTime * absFollowSpeed;
            float traveled;

            Evaluate(Travel(input.percent, travelDistance, direction, out traveled), input);

            if (traveled < travelDistance && ((direction == Spline.Direction.Forward && input.percent > 0.99999) || (direction == Spline.Direction.Backward && input.percent < 0.00001)))
            {
                //we have reached the end of the segment
                if (direction == Spline.Direction.Forward)
                {
                    if (_segment.next != null)
                    {
                        _segment = _segment.next;
                        OnEnteredSegment(_segment);
                        Evaluate(Travel(0.0, travelDistance - traveled, direction, out traveled), input);
                    }
                }
                else
                {
                    if (_segment.previous != null)
                    {
                        _segment = _segment.previous;
                        OnEnteredSegment(_segment);
                        Evaluate(Travel(1.0, travelDistance - traveled, direction, out traveled), input);
                    }
                }
            }
        }
Пример #22
0
        public static void DrawGeneratedSpline(LevelSegment segment)
        {
            Vector3 cameraPos = SceneView.currentDrawingSceneView.camera.transform.position;

            Handles.color = ForeverPrefs.pointColor;
            //Debug spline points
            if (segment.path != null)
            {
                for (int i = 0; i < segment.path.spline.points.Length; i++)
                {
                    Vector3 pos        = segment.path.spline.points[i].position;
                    float   handleSize = HandleUtility.GetHandleSize(segment.path.spline.points[i].position);
                    Handles.DrawSolidDisc(pos, cameraPos - pos, handleSize * 0.1f);
                    Handles.DrawLine(pos, pos + segment.path.spline.points[i].normal * segment.drawSampleScale);
                    if (segment.path.spline.type == Spline.Type.Bezier)
                    {
                        Handles.DrawDottedLine(segment.path.spline.points[i].position, segment.path.spline.points[i].tangent, 10f);
                        Handles.DrawDottedLine(segment.path.spline.points[i].position, segment.path.spline.points[i].tangent2, 10f);
                        Handles.DrawWireDisc(segment.path.spline.points[i].tangent, cameraPos - segment.path.spline.points[i].tangent, handleSize * 0.075f);
                        Handles.DrawWireDisc(segment.path.spline.points[i].tangent2, cameraPos - segment.path.spline.points[i].tangent2, handleSize * 0.075f);
                    }
                }
            }
        }
Пример #23
0
        IEnumerator CreateSegment()
        {
            while (!levels[levelIndex].isReady && !testMode)
            {
                yield return(null);
            }
            HandleLevelChange();
            while (LevelSegment.generationState != LevelSegment.GenerationState.Idle)
            {
                yield return(null);
            }
            if (levels[levelIndex].IsDone() && !testMode)
            {
                yield break;
            }
            LevelSegment segment = null;

            if (testMode)
            {
                GameObject go = Instantiate(debugSegments[Random.Range(0, debugSegments.Length)]);
                segment = go.GetComponent <LevelSegment>();
            }
            else
            {
                segment = levels[levelIndex].InstantiateSegment();
            }
            Transform  segmentTrs = segment.transform;
            Vector3    spawnPos   = segmentTrs.position;
            Quaternion spawnRot   = segmentTrs.rotation;

            if (segments.Count > 0)
            {
                SplineSample lastSegmentEndResult = new SplineSample();
                _segments[_segments.Count - 1].Evaluate(1.0, lastSegmentEndResult);
                spawnPos = lastSegmentEndResult.position;
                spawnRot = lastSegmentEndResult.rotation;
                switch (segment.axis)
                {
                case LevelSegment.Axis.X: spawnRot = Quaternion.AngleAxis(90f, Vector3.up) * spawnRot; break;

                case LevelSegment.Axis.Y: spawnRot = Quaternion.AngleAxis(90f, Vector3.right) * spawnRot; break;
                }
            }

            segmentTrs.position = spawnPos;
            if (segment.objectProperties[0].extrusionSettings.applyRotation)
            {
                segmentTrs.rotation = spawnRot;
            }


            if (segment.type == LevelSegment.Type.Extruded)
            {
                switch (segment.axis)
                {
                case LevelSegment.Axis.X:
                    segment.transform.position += segment.transform.right * segment.GetBounds().size.x;
                    break;

                case LevelSegment.Axis.Y:
                    segment.transform.position += segment.transform.up * segment.GetBounds().size.y;
                    break;

                case LevelSegment.Axis.Z:
                    segment.transform.position += segment.transform.forward * segment.GetBounds().size.z;
                    break;
                }
            }

            if (_segments.Count > 0)
            {
                segment.previous = _segments[_segments.Count - 1];
            }
            segment.level = levels[levelIndex];

            if (segment.type == LevelSegment.Type.Custom)
            {
                Quaternion entranceRotationDelta = segment.customEntrance.rotation * Quaternion.Inverse(spawnRot);
                segment.transform.rotation = segment.transform.rotation * Quaternion.Inverse(entranceRotationDelta);
                if (segment.customKeepUpright)
                {
                    segment.transform.rotation = Quaternion.FromToRotation(segment.customEntrance.up, Vector3.up) * segment.transform.rotation;
                }
                Vector3 entranceOffset = segment.transform.position - segment.customEntrance.position;
                segment.transform.position = spawnPos + entranceOffset;
            }

            if (segmentIndex == int.MaxValue)
            {
                segmentIndex = 2;
            }
            segment.Initialize(segmentIndex++);
            segment.transform.parent = transform;
            currentPathGenerator.GeneratePath(segment);
            _segments.Add(segment);
            //Remove old segments
            if (type == Type.Infinite && _segments.Count > maxSegments)
            {
                StartCoroutine(CleanupRoutine());
            }
            if (levels[levelIndex].IsDone() && !testMode)
            {
                if (levelIteration == LevelIteration.Ordered && levelIndex >= levels.Length - 1)
                {
                    if (onLevelsDepleted != null)
                    {
                        onLevelsDepleted();
                    }
                    yield break;
                }
                if (levelIteration == LevelIteration.None)
                {
                    if (onLevelsDepleted != null)
                    {
                        onLevelsDepleted();
                    }
                    yield break;
                }
                NextLevel();
            }
        }
Пример #24
0
 public override void StartFollow(LevelSegment segment, double percent)
 {
     lane = lastLane = startLane;
     base.StartFollow(segment, percent);
 }
Пример #25
0
 public void AddToBuildQueue(LevelSegment input)
 {
     buildQueue.Add(input);
 }
Пример #26
0
 internal LevelSegmentPath(LevelSegment s)
 {
     segment   = s;
     transform = s.transform;
     spline    = new Spline(Spline.Type.Bezier);
 }
Пример #27
0
        /// <summary>
        /// Generates the path for a level segment
        /// </summary>
        /// <param name="inputSegment"></param>
        /// <returns></returns>
        public void GeneratePath(LevelSegment inputSegment)
        {
            if (controlPointsPerSegment < 2)
            {
                controlPointsPerSegment = 2;
            }
            segment = inputSegment;
            if (level != segment.level)
            {
                _isNewLevel = true;
                level       = segment.level;
                OnNewLevel();
            }
            if (segment.type == LevelSegment.Type.Custom)
            {
                lastPoint = new SplinePoint(segment.customExit.position, segment.customExit.position + segment.customExit.forward, segment.customExit.up, 1f, Color.white);
                InverseTransformPoint(ref lastPoint);
                _isNewLevel = false;
                return;
            }

            customRule    = segment.GetComponent <CustomPathRule>();
            useCustomRule = customRule != null;

            //Create points array
            SplinePoint[] points = new SplinePoint[controlPointsPerSegment];
            for (int i = 0; i < points.Length; i++)
            {
                points[i] = new SplinePoint();
            }

            pointStartIndex = 0;
            if (segment.previous != null)
            {
                if (segment.previous.path != null)
                {
                    points[0]       = lastPoint;
                    pointStartIndex = 1;
                }
                else if (segment.previous.customExit != null)
                {
                    Transform exit = segment.previous.customExit;
                    points[0]       = new SplinePoint(exit.position, exit.position - exit.forward * GetPointDistance() / 3f, exit.up, 1f, Color.white);
                    pointStartIndex = 1;
                }
            }

            OnBeforeGeneration(points);

            if (useCustomRule)
            {
                customRule.segment = segment;
                customRule.OnBeforeGeneration(this);
            }
            for (int i = pointStartIndex; i < points.Length; i++)
            {
                if (i == 0 && segment.previous == null)
                {
                    _isFirstPoint = true;
                }
                GeneratePoint(ref points[i], i);
                _isFirstPoint = false;
                lastPoint     = points[i];
            }
            OnPostGeneration(points);
            if (useCustomRule)
            {
                customRule.OnPostGeneration(points);
            }


            lastPoint   = points[points.Length - 1];
            _isNewLevel = false;

            for (int i = 0; i < points.Length; i++)
            {
                points[i].position = transform.TransformPoint(points[i].position);
                points[i].tangent  = transform.TransformPoint(points[i].tangent);
                points[i].tangent2 = transform.TransformPoint(points[i].tangent2);
                points[i].normal   = transform.TransformDirection(points[i].normal).normalized;
            }
            Spline spline = new Spline((Spline.Type)pathType, 10);

            spline.customNormalInterpolation = normalInterpolation;
            spline.customValueInterpolation  = valueInterpolation;
            spline.points       = points;
            segment.path.spline = spline;
            segment.sampleRate  = sampleRate;
        }