예제 #1
0
        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);
        }
예제 #2
0
        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);
        }