Exemple #1
0
    private GameObject GetChunkPrefab(TrackChunk.ChunkType direction, int heightDiff)
    {
        GameObject result = null;

        if (direction == TrackChunk.ChunkType.STRAIGHT)
        {
            if (heightDiff == 0)
            {
                result = chunkPrefabs.chunkStraight;
            }
            else if (heightDiff == -1)
            {
                result = chunkPrefabs.chunkDown;
            }
            else if (heightDiff == 1)
            {
                result = chunkPrefabs.chunkUp;
            }
        }
        else if (direction == TrackChunk.ChunkType.CURVE_LEFT)
        {
            result = chunkPrefabs.chunkTurnLeft;
        }
        else if (direction == TrackChunk.ChunkType.CURVE_RIGHT)
        {
            result = chunkPrefabs.chunkTurnRight;
        }

        return(result);
    }
Exemple #2
0
    private void FinalizeCloseCircuit(HashSet <TrackNode> track, SearchNode endNode)
    {
        Stack <SearchNode> path    = new Stack <SearchNode>();
        SearchNode         current = endNode;

        while (current != null)
        {
            path.Push(current);
            current = current.parent;
        }

        while (path.Count > 0)
        {
            SearchNode node = path.Pop();
            SearchNode next = null;
            if (path.Count > 0)
            {
                next = path.Peek();
            }

            int heightDiff = 0;
            TrackChunk.ChunkType chunkType = TrackChunk.ChunkType.STRAIGHT;

            if (next != null)
            {
                heightDiff = next.parentHeightDiff;
                chunkType  = next.parentType;
            }

            TrackNode trackNode = new TrackNode(node.pos, node.rotation);
            trackNode.heightDiff = heightDiff;
            trackNode.chunkType  = chunkType;
            track.Add(trackNode);
            trackOrderedChunks.Add(trackNode);
        }
    }
Exemple #3
0
    public void GenerateTrack()
    {
        difficulty = Mathf.Clamp01(difficulty);
        length     = Mathf.Clamp(length, MIN_LENGTH, MAX_LENGTH);

        HashSet <TrackNode> nodes = new HashSet <TrackNode>();

        // Start one block forward
        IntVector3 cursor = new IntVector3();

        cursor.z = 1;

        float heightChangeProb = HEIGHT_CHANGE_PROB * difficulty;
        int   remainingChunks  = length;
        int   currentRotation  = 0;
        bool  done             = false;

        int firstStretchLen = 0;
        int countdown       = INITIAL_GENERATION_TIMEOUT * length;

        while (!done)
        {
            if (countdown-- < 0)
            {
                throw new InvalidTrackException("Initial track generation timed out.");
            }

            int heightDiff = 0;
            TrackChunk.ChunkType direction = TrackChunk.ChunkType.STRAIGHT;

            if (firstStretchLen > FIRST_STRETCH_LEN)
            {
                if (rand.NextDouble() < heightChangeProb)
                {
                    heightDiff = (rand.NextDouble() < 0.5 ? 1 : -1);
                }

                // Decide Direction
                if (heightDiff == 0 && rand.NextDouble() < DIRECTION_TURN_PROB * difficulty)
                {
                    if (rand.NextDouble() < 0.5)
                    {
                        direction = TrackChunk.ChunkType.CURVE_LEFT;
                    }
                    else
                    {
                        direction = TrackChunk.ChunkType.CURVE_RIGHT;
                    }
                }
            }

            firstStretchLen++;

            int nextRotation = currentRotation;

            // Update rotation
            if (direction == TrackChunk.ChunkType.CURVE_RIGHT)
            {
                nextRotation += 90;
            }
            else if (direction == TrackChunk.ChunkType.CURVE_LEFT)
            {
                nextRotation -= 90;
            }

            nextRotation = ClampRotation(nextRotation);

            IntVector3 nextPos = GetNextPoint(cursor, nextRotation, 0);

            if (HasNodeAt(nodes, nextPos))
            {
                continue;
            }

            if (heightDiff == 0)
            {
                IntVector3 nextPosUp   = GetNextPoint(cursor, nextRotation, 1);
                IntVector3 nextPosDown = GetNextPoint(cursor, nextRotation, -1);

                if (HasNodeAt(nodes, nextPosUp) || HasNodeAt(nodes, nextPosDown))
                {
                    continue;
                }
            }
            else
            {
                IntVector3 nextPosHDiff = GetNextPoint(cursor, nextRotation, heightDiff);
                if (HasNodeAt(nodes, nextPosHDiff))
                {
                    continue;
                }
            }

            nextPos.y += heightDiff;

            TrackNode node = new TrackNode(cursor, currentRotation);
            node.chunkType  = direction;
            node.heightDiff = heightDiff;
            nodes.Add(node);
            trackOrderedChunks.Add(node);

            currentRotation = nextRotation;
            cursor          = nextPos;

            if (firstStretchLen > FIRST_STRETCH_LEN)
            {
                remainingChunks--;
            }

            if (remainingChunks == 0)
            {
                done = true;
            }
        }

        // Now, close the circuit

        bool ok = CloseCircuit(nodes, cursor, currentRotation);

        // Instance prefabs
        List <TrackChunk> instancedChunks = InstanceChunkClones(trackOrderedChunks);

        if (!ok)
        {
            throw new InvalidTrackException("A* pathfinding timed out.");
        }
        else
        {
            RacingTrack rt = trackBase.AddComponent <RacingTrack>();
            rt.trackChunks = instancedChunks;
            rt.startChunk  = instancedChunks[0];
            rt.endChunk    = instancedChunks[instancedChunks.Count - 1];
        }
    }