internal void MigrateOldCustompath(LevelSegmentCustomPath old) { segment = old.segment; transform = old.transform; spline = old.spline; localPoints = old.localPoints; }
protected virtual void OnEnteredSegment(LevelSegment entered) { if (isPlayerInstance) { entered.Enter(); } }
public LevelSegment Instantiate() { GameObject go = Object.Instantiate(_prefab); LevelSegment seg = go.GetComponent <LevelSegment>(); return(seg); }
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; }
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); }
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; }
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; }
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; }
public void Stop() { if (buildThread != null && buildThread.IsAlive) { buildThread.Abort(); } buildQueue.Clear(); buildSegment = null; postBuild = false; }
/// <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; }
// 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++; } }
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(); } }
/// <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; }
private void Init(LevelSegment input, double percentAlong = 0.0) { _segment = input; Evaluate(percentAlong, _result); if (isPlayerInstance) { _segment.Enter(); } OnEnteredSegment(_segment); RefreshTargets(); }
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; } }
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; }
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); } }
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; }
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; } } }
public void StartBuild(LevelSegment segment) { if (_isDone) { return; } if (_isBuilding) { return; } if (buildQueued) { return; } levelSegment = segment; buildQueued = true; Build(); StartCoroutine(BuildRoutine()); }
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); } } } }
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); } } } }
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(); } }
public override void StartFollow(LevelSegment segment, double percent) { lane = lastLane = startLane; base.StartFollow(segment, percent); }
public void AddToBuildQueue(LevelSegment input) { buildQueue.Add(input); }
internal LevelSegmentPath(LevelSegment s) { segment = s; transform = s.transform; spline = new Spline(Spline.Type.Bezier); }
/// <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; }