private void CreateObjects(LevelHolder levelHolder) { var allEntities = new List <RoadEntityData>(); var splines = levelHolder._lines; var points = levelHolder.GetComputer().GetPoints(); for (var i = 0; i < points.Length; i++) { for (var j = 0; j < _track[i].Lines.Length; j++) { foreach (var item in _track[i].Lines[j].values) { var point = splines[j].Evaluate(splines[j].Project(splines[j].GetPoint(i).position)); TrackPrefabs.TrackObject prefab = null; IList <GameObject> list = null; switch (item) { case TrackItem.Magnet: { prefab = _prefabs.Magnet; break; } case TrackItem.Obstacle: { prefab = _prefabs.Obstacle; list = levelHolder.barriers; allEntities.Add(RoadEntityData.CreateBarrier(BarrierType.Ground_SingePath, i / (float)(points.Length - 1), 0.5f, j)); break; } case TrackItem.ObstacleHard: { prefab = _prefabs.ObstacleBlock; list = levelHolder.barriers; allEntities.Add(RoadEntityData.CreateBarrier(BarrierType.Ground_SingePath, i / (float)(points.Length - 1), 1.5f, j)); break; } case TrackItem.EnemyGround: { prefab = _prefabs.EnemyGround; list = levelHolder.enemies; allEntities.Add(RoadEntityData.CreateEnemy(EnemyType.Ground, i / (float)(points.Length - 1), 0.5f, j)); break; } case TrackItem.EnemyAir: { prefab = _prefabs.EnemyAir; list = levelHolder.enemies; allEntities.Add(RoadEntityData.CreateEnemy(EnemyType.Fly, i / (float)(points.Length - 1), 0.5f, j)); break; } case TrackItem.Shield: { prefab = _prefabs.Shield; break; } case TrackItem.Accelerator: { prefab = _prefabs.Accelerator; list = levelHolder.boosters; break; } } if (prefab != null) { var obj = (GameObject)PrefabUtility.InstantiatePrefab(prefab.prefab); obj.transform.rotation = Quaternion.LookRotation(point.direction, point.normal); obj.transform.position = point.position + point.rotation * prefab.offset; obj.transform.parent = splines[j].transform; list?.Add(obj); } CreateCoins(_track[i].Lines[j].values.Where(t => t == TrackItem.CoinLow || t == TrackItem.CoinMiddle || t == TrackItem.CoinHigh).ToArray(), point, splines[j].transform, levelHolder.money, allEntities, j); } EditorUtility.DisplayProgressBar("Create track objects", $"Line #{j + 1} of {_track[i].Lines.Length} :: Point: {i + 1} of {points.Length}", i / (float)(points.Length - 1)); } } levelHolder.allEntities = allEntities; EditorUtility.ClearProgressBar(); eGUI.SetDirty(levelHolder.gameObject); }
private void CreateLines(LevelHolder levelHolder) { var spline = levelHolder.GetComputer(); var deviance = new float[_lines]; var points = spline.GetPoints(); var tracks = new SplinePoint[_lines][]; // calc line deviance from center for (var i = 0; i < _lines; i++) { deviance[i] = _linesInterval * (i - (_lines - 1) / 2f); tracks[i] = new SplinePoint[points.Length]; } var trackSurfaces = new List <TrackInterval> [_lines]; for (var i = 0; i < _lines; i++) { trackSurfaces[i] = new List <TrackInterval>(); } var offset = new Vector3[_lines]; // create points for lines & calc intervals for mesh for (var i = 0; i < points.Length; i++) { EditorUtility.DisplayProgressBar("Create points for lines & calc intervals for mesh", $" Point {i + 1} of {points.Length}", i / (float)(points.Length - 1)); for (var line = 0; line < _lines; line++) { var currSurface = _track[i].Lines[line].surface; if (i == 0) { var ti = new TrackInterval { type = currSurface, start = 0, end = 0, segments = 0 }; trackSurfaces[line].Add(ti); } else if (i == points.Length - 1) { trackSurfaces[line][trackSurfaces[line].Count - 1].end = 1d; trackSurfaces[line][trackSurfaces[line].Count - 1].segments = i - trackSurfaces[line][trackSurfaces[line].Count - 1].segments; } else { var prevSurface = _track[i - 1].Lines[line].surface; if (currSurface != prevSurface) { trackSurfaces[line][trackSurfaces[line].Count - 1].end = (i) / (double)(points.Length - 1); trackSurfaces[line][trackSurfaces[line].Count - 1].segments = i - trackSurfaces[line][trackSurfaces[line].Count - 1].segments; var ti2 = new TrackInterval { start = i / (double)(points.Length - 1), type = currSurface, segments = i }; trackSurfaces[line].Add(ti2); } } var pos = spline.Project(points[i].position); var p = spline.Evaluate(pos); foreach (var dir in _track[i].Lines[line].dirs) { switch (dir) { case TrackDir.ShiftLeft: offset[line].x += -_stepHorizontalShift; break; case TrackDir.ShiftRight: offset[line].x += _stepHorizontalShift; break; case TrackDir.ShiftUp: offset[line].y += _stepVerticalShift; break; case TrackDir.ShiftDown: offset[line].y += -_stepVerticalShift; break; default: throw new ArgumentOutOfRangeException(); } } var p2 = points[i].position + p.right * deviance[line] + (Quaternion.LookRotation(p.direction, p.normal) * offset[line]); tracks[line][i].position = p2; tracks[line][i].size = _linesInterval; tracks[line][i].normal = points[i].normal; } { var p = spline.Evaluate(spline.Project(points[i].position)).position; var pos0 = tracks[0][i].position - p; var pos1 = tracks[_lines - 1][i].position - p; if (_track[i].dir.Any(t => t == TrackDir.RotateLeft || t == TrackDir.RotateRight)) { var dy = Mathf.Max(pos0.y, pos1.y); foreach (var track in tracks) { track[i].position.y += dy; } } } } var splines = new List <SplineComputer>(_lines); // create splines from lines & set SplineMesh for road bake for (var i = 0; i < _lines; i++) { var go = new GameObject($"Line_{i}"); go.transform.parent = spline.gameObject.transform; var s = go.AddComponent <SplineComputer>(); splines.Add(s); s.space = SplineComputer.Space.Local; s.SetPoints(tracks[i]); s.type = Spline.Type.BSpline; s.RebuildImmediate(); var sm = go.AddComponent <SplineMesh>(); sm.computer = s; sm.RemoveChannel(0); var divider = int.MaxValue; foreach (var interval in trackSurfaces[i]) { if (divider > interval.segments) { divider = interval.segments; } } divider = _simplifyTrackMeshes ? divider : 1; for (var index = 0; index < trackSurfaces[i].Count; index++) { EditorUtility.DisplayProgressBar("Create lines & road bake", $"Line #{i + 1} of {_lines} :: Interval: {index} of {trackSurfaces[i].Count - 1}", index / (float)(trackSurfaces[i].Count - 1)); var interval = trackSurfaces[i][index]; var md = interval.type == TrackSurface.Railroad ? _prefabs.Rails : _prefabs.Normal; var channel = sm.AddChannel($"{interval.type}"); channel.minScale = md.scale; channel.maxScale = md.scale; channel.minOffset = md.offset; channel.maxOffset = md.offset; channel.AddMesh(md.mesh); channel.count = interval.segments / divider; channel.clipFrom = interval.start; channel.clipTo = interval.end; } EditorUtility.DisplayProgressBar("Create lines & road bake", $"Line #{i + 1} of {_lines} :: Build mesh", 0); sm.RebuildImmediate(true); sm.Rebuild(true); var mr = sm.gameObject.GetComponent <MeshRenderer>(); mr.sharedMaterial = _prefabs.RoadMaterial; mr.shadowCastingMode = ShadowCastingMode.Off; mr.receiveShadows = false; mr.lightProbeUsage = LightProbeUsage.Off; mr.reflectionProbeUsage = ReflectionProbeUsage.Off; } levelHolder.Init(spline); levelHolder.Init(splines.ToArray(), _linesInterval); { for (var i = 0; i < points.Length; i++) { if (_track[i].dir.Any(t => t == TrackDir.Fence)) { var p = splines[0].Evaluate(i); var go = Instantiate(_prefabs.Fence.prefab).transform; go.position = p.position - p.right * _linesInterval * 0.5f; go.rotation = p.rotation; go.localScale = Vector3.one * _stepLength; go.parent = splines[0].transform; p = splines[_lines - 1].Evaluate(i); go = Instantiate(_prefabs.Fence.prefab).transform; go.position = p.position + p.right * _linesInterval * 0.5f; go.rotation = p.rotation; go.localScale = Vector3.one * _stepLength; go.parent = splines[_lines - 1].transform; } } } levelHolder.barriers = new List <GameObject>(); levelHolder.boosters = new List <GameObject>(); levelHolder.enemies = new List <GameObject>(); levelHolder.money = new List <GameObject>(); levelHolder.intervals = new LevelHolder.TrackSurface[trackSurfaces.Length]; for (var i = 0; i < trackSurfaces.Length; i++) { levelHolder.intervals[i] = new LevelHolder.TrackSurface(trackSurfaces[i]); } CreateObjects(levelHolder); }