Пример #1
0
    public void GenerateNextSegment(bool visualize = true, bool generateObstacles = true)
    {
        var config = levelSO.currentStage.Next();

        var seggy = LevelGenerator.GenerateLevel(config);

        seggy.index = latestSegmentIndex;
        levelSegments.Add(seggy);

        LevelGenerator.Segment currentSegment = levelSegments[levelSegments.Count - 1];
        LevelGenerator.Segment prevSegment    = (levelSegments.Count < 2) ? null : levelSegments[levelSegments.Count - 2];

        if (visualize)
        {
            Vector3 position = new Vector3(0, -0.5f, segmentLength * currentSegment.index);
            currentSegment.gameObject      = Instantiate(levelSO.levelSegmentPrefab[0], LevelSegmentsHolder.transform);
            currentSegment.gameObject.name = "Segment " + currentSegment.index;
            currentSegment.gameObject.transform.localPosition = position;
        }

        if (visualize && prevSegment != null && prevSegment.gameObject == null)
        {
            visualize = false;
        }

        // Scenery
        if (prevSegment != null)
        {
            while (true)
            {
                var buildingInfo = levelSO.buildingPrefabs[Random.Range(0, levelSO.buildingPrefabs.Length)];
                if (prevSegment.leftLastBuilding + buildingInfo.size < segmentLength)
                {
                    if (visualize)
                    {
                        var building = Instantiate(buildingInfo.prefab, prevSegment.gameObject.transform);
                        building.transform.localPosition = new Vector3(-10f, 0f, prevSegment.leftLastBuilding);
                    }
                    prevSegment.leftLastBuilding += buildingInfo.size;
                }
                else
                {
                    currentSegment.leftLastBuilding = prevSegment.leftLastBuilding - segmentLength;
                    break;
                }
            }
            while (true)
            {
                var buildingInfo = levelSO.buildingPrefabs[Random.Range(0, levelSO.buildingPrefabs.Length)];
                if (prevSegment.rightLastBuilding + buildingInfo.size < segmentLength)
                {
                    if (visualize)
                    {
                        var building = Instantiate(buildingInfo.prefab, prevSegment.gameObject.transform);
                        building.transform.localPosition = new Vector3(10f, 0f, prevSegment.rightLastBuilding);
                        building.transform.localScale    = new Vector3(-1f, 1f, 1f);
                    }
                    prevSegment.rightLastBuilding += buildingInfo.size;
                }
                else
                {
                    currentSegment.rightLastBuilding = prevSegment.rightLastBuilding - segmentLength;
                    break;
                }
            }
        }

        // More scenery
        if (Random.Range(0f, 1f) <= .5f)
        {
            if (visualize)
            {
                var newSide = Instantiate(levelSO.sidePrefabs[Random.Range(0, levelSO.buildingPrefabs.Length)], currentSegment.gameObject.transform);
                newSide.transform.localPosition    = new Vector3(-8f, .5f, 4f);
                newSide.transform.localEulerAngles = new Vector3(0f, 0f, 0f);
            }
            else
            {
                Random.Range(0, levelSO.buildingPrefabs.Length);
            }
        }

        if (Random.Range(0f, 1f) <= .5f)
        {
            if (visualize)
            {
                var newSide = Instantiate(levelSO.sidePrefabs[Random.Range(0, levelSO.buildingPrefabs.Length)], currentSegment.gameObject.transform);
                newSide.transform.localPosition    = new Vector3(8f, .5f, 4f);
                newSide.transform.localEulerAngles = new Vector3(0f, 180f, 0f);
            }
            else
            {
                Random.Range(0, levelSO.buildingPrefabs.Length);
            }
        }

        if (generateObstacles)
        {
            // Obstacles generation
            List <List <LevelGenerator.Obstacle> > subsegments = new List <List <LevelGenerator.Obstacle> >();
            for (int j = 0; j < laneCount; j++)
            {
                var obstacle = GetObstacle(currentSegment, j);

                if (obstacle == null)
                {
                    continue;
                }

                List <LevelGenerator.Obstacle> subsegment = new List <LevelGenerator.Obstacle>
                {
                    obstacle
                };
                while (j < laneCount)
                {
                    var nextObstacle = GetObstacle(currentSegment, j + 1);
                    if (nextObstacle != null && nextObstacle.unpassable == obstacle.unpassable && nextObstacle.slidable == obstacle.slidable)
                    {
                        subsegment.Add(nextObstacle);
                        j++;
                    }
                    else
                    {
                        break;
                    }
                }

                subsegments.Add(subsegment);
            }

            // Obstacle visualization
            for (int j = 0; j < subsegments.Count; j++)
            {
                var subsegment = subsegments[j];
                List <LevelSO.ObstacleSegment> segments = new List <LevelSO.ObstacleSegment>();
                foreach (var obstacle in subsegment)
                {
                    segments.Add(new LevelSO.ObstacleSegment()
                    {
                        slidable = obstacle.slidable, unpassable = obstacle.unpassable
                    });
                }

                var obs = ObstacleManager.GetObstacle(new LevelSO.ObstacleInfo()
                {
                    width = subsegment.Count, segments = segments
                }, new List <LevelSO.ObstacleInfo>(levelSO.obstaclePrefabs));

                if (obs.Count == 0)
                {
                    if (subsegment.Count == 1)
                    {
                        throw new System.Exception("Something is not right.");
                    }

                    var lastElement = subsegment[subsegment.Count - 1];
                    subsegments.Add(new List <LevelGenerator.Obstacle>()
                    {
                        lastElement
                    });
                    subsegment.RemoveAt(subsegment.Count - 1);
                    var remainder = new List <LevelGenerator.Obstacle>(subsegment);
                    subsegments.Add(subsegment);
                }
                else
                {
                    if (visualize)
                    {
                        var      prefabToInstantiate = obs[Random.Range(0, obs.Count)];
                        var      obstacleGameObject  = Instantiate(prefabToInstantiate.prefab, currentSegment.gameObject.transform);
                        Obstacle obstacle            = obstacleGameObject.AddComponent <Obstacle>();
                        obstacle.ObstacleInfo = prefabToInstantiate;
                        obstacleGameObject.transform.localPosition = new Vector3((subsegment[0].index - 1) * 4f, 0.5f, segmentLength / 2);
                    }
                    else
                    {
                        Random.Range(0, obs.Count);
                    }
                }
            }
        }

        latestSegmentIndex++;
    }