public Mesh CreateSectionMesh(TrackSection section)
    {
        int  subdivisions = Mathf.CeilToInt(section.length / length);
        Mesh mesh         = new Mesh();

        Vector3[] vertices  = new Vector3[2 + subdivisions * 2];
        Vector2[] uvs       = new Vector2[2 + subdivisions * 2];
        int[]     triangles = new int[subdivisions * 2 * 6];

        int vertexIndex   = 0;
        int triangleIndex = 0;

        float distance = 0.0f;

        for (int i = 0; i < subdivisions + 1; i++)
        {
            if (i == subdivisions)
            {
                distance = section.length;
            }

            Vector3    center  = section.GetPositionOnTrack(distance).Vector3() - section.position.Vector3() + Vector3.up * 0.01f;
            Quaternion angle   = Quaternion.AngleAxis(270f - (float)section.GetRotationOnTrack(distance).Degrees, Vector3.up);
            Vector3    tangent = angle * Vector3.forward;

            Vector3 right = Vector3.Cross(tangent, Vector3.up) * width * 0.5f;
            Vector3 left  = -right;

            vertices[vertexIndex]     = left + center;
            vertices[vertexIndex + 1] = right + center;

            uvs[vertexIndex]     = new Vector2(0, i);
            uvs[vertexIndex + 1] = new Vector2(1, i);

            //Debug.Log("i: " + i + " center: " + center.ToString() + " left: " + left.ToString() + " right " + right.ToString());
            if (i > 0.0f)
            {
                triangles[triangleIndex]     = vertexIndex - 2;
                triangles[triangleIndex + 1] = vertexIndex + 1;
                triangles[triangleIndex + 2] = vertexIndex - 1;

                triangles[triangleIndex + 3] = vertexIndex - 2;
                triangles[triangleIndex + 4] = vertexIndex;
                triangles[triangleIndex + 5] = vertexIndex + 1;
                triangleIndex += 6;
            }
            vertexIndex += 2;

            distance += section.length / (float)subdivisions;
        }

        mesh.vertices  = vertices;
        mesh.triangles = triangles;
        mesh.uv        = uvs;
        //mesh.RecalculateNormals();


        return(mesh);
    }
Beispiel #2
0
    private Vector3 GetSnappedTrackPosition(TrackSection section, Vector3 point, out float distance)
    {
        // TODO: This doesn't find tracks with both endpoints in a different sector than the hit...
        const float testResolution = 3.0f;

        distance = 0;
        float distanceFromPoint = float.MaxValue;
        float delta             = Mathf.Min(testResolution, section.Length / 2);

        while (distance < section.Length)
        {
            var newDistance          = distance + delta;
            var newDistanceFromPoint = Vector3.Distance(point, section.GetPositionOnTrack(newDistance));
            if (newDistanceFromPoint > distanceFromPoint)
            {
                break;
            }
            distance          = newDistance;
            distanceFromPoint = newDistanceFromPoint;
        }

        distance = Mathf.Clamp(distance, 0, section.Length);
        return(section.GetPositionOnTrack(distance));
    }
Beispiel #3
0
    //Warning: Recursive
    public bool Move(float distance)
    {
        bool hasMoved = false;

        float newPosition = position + distance * (int)direction;

        if (currentTrackSection.GetPositionOnTrack(newPosition) != null)
        {
            //Do the thing
            position = newPosition;
            hasMoved = true;
        }
        else
        {
            TrackSection newSection = (direction == Direction.Forward) ? TrackCollection.instance.Get(currentTrackSection.NextSectionIndex) : TrackCollection.instance.Get(currentTrackSection.PreviousSectionIndex);
            if (newSection != null)
            {
                //Check to see if we need to switch direction
                Direction newDirection         = direction;
                float     distanceOnNewSection = 0.0f;
                float     positionOnNewSection = 0.0f;

                if (direction == Direction.Forward)
                {
                    distanceOnNewSection = newPosition - currentTrackSection.length;

                    //TODO: Make a function to determine the correct direction in the TrackSection class
                    //Might be needed when working with switches, so we can override it in that case
                    if (newSection.CheckNextSection(currentTrackSection))
                    {
                        newDirection         = Direction.Reverse;
                        positionOnNewSection = newSection.length;
                    }
                }
                else
                {
                    distanceOnNewSection = -newPosition;
                    positionOnNewSection = newSection.length;

                    if (newSection.CheckPreviousSection(currentTrackSection))
                    {
                        newDirection         = Direction.Forward;
                        positionOnNewSection = 0.0f;
                    }
                }
                //TODO: Try to get a stack overflow by calling move with a really high distance value
                Traveler traveler = new Traveler(newSection, newDirection, positionOnNewSection);
                hasMoved = traveler.Move(distanceOnNewSection);

                this.direction           = traveler.direction;
                this.currentTrackSection = traveler.currentTrackSection;
                this.position            = traveler.position;
            }
            else
            {
                //There was no new section!
                //TODO: Derail, move to the end or something else?
                UnityEngine.Debug.Log("Traveler got stuck at track section " + currentTrackSection.index);
                Derail();
            }
        }
        return(hasMoved);
    }
    public static void CreateTrackLayout()
    {
        TrackCollection trackCollection = TrackCollection.GetInstance();

        /*
         * TrackSection a = new TrackSection(new WorldPosition(0, 0, 20f, 20f), new WorldRotation(25, false), 750f, true, 90f);
         * trackCollection.Add(a);
         * TrackSection b = a.CreateNext(750f, true, 90f);
         * b = b.CreateNext(750f, true, 90f);
         * b = b.CreateNext(750f, true, 90f);
         *
         * b.NextSectionIndex = a.index;
         * a.PreviousSectionIndex = b.index;
         */



        // Create start section
        TrackSection start = new TrackSection(new WorldPosition(0, 0, 20f, 10f), new WorldRotation(-100.0f, false), 200.0f);

        trackCollection.Add(start);
        TrackSection currentSection = start;

        currentSection = currentSection.CreateNext(100.0f, false, 0.0f);

        // Create a new junction
        TrackJunction junction = new TrackJunction(currentSection.GetPositionOnTrack(currentSection.length), currentSection.GetRotationOnTrack(currentSection.length));

        trackCollection.Add(junction);
        // Attach it to the previous section
        junction.PreviousSectionIndex   = currentSection.index;
        currentSection.NextSectionIndex = junction.index;

        // Create the junction sections
        TrackSection switchSectionCurved = junction.CreateSection(200.0f, true, 90.0f);
        // 127.32395447351626861510701069801
        TrackSection switchSectionStraight = junction.CreateSection(2.0f * 127.32395f, false, 0.0f);

        // Create a loop
        currentSection = switchSectionStraight;
        // NOTE: It's split into two parts because junction sections from the same junction need at least 2 other section before they connect to eachother
        currentSection = currentSection.CreateNext(200.0f, true, 90.0f);
        currentSection = currentSection.CreateNext(400.0f, true, 180.0f);
        // Join it up
        currentSection.NextSectionIndex      = switchSectionCurved.index;
        switchSectionCurved.NextSectionIndex = currentSection.index;

        // Create a new piece of track on the other end of the start piece
        currentSection = new TrackSection(start.position, start.rotation.Oppisite, 20.0f);
        currentSection.PreviousSectionIndex = start.index;
        start.PreviousSectionIndex          = trackCollection.Add(currentSection);

        // Create a new junction
        junction = new TrackJunction(currentSection.GetPositionOnTrack(currentSection.length), currentSection.GetRotationOnTrack(currentSection.length));
        trackCollection.Add(junction);

        // Attach it to the previous section
        junction.PreviousSectionIndex   = currentSection.index;
        currentSection.NextSectionIndex = junction.index;
        // Create the junction sections
        switchSectionCurved = junction.CreateSection(200.0f, true, 90.0f);
        //127.32395447351626861510701069801
        switchSectionStraight = junction.CreateSection(2.0f * 127.32395f, false, 0.0f);

        // Create a loop
        currentSection = switchSectionStraight;
        // NOTE: It's split into two parts because junction sections from the same junction need at least 2 other section before they connect to eachother
        // Add a junction and attach it
        junction = new TrackJunction(currentSection.GetPositionOnTrack(currentSection.length), currentSection.GetRotationOnTrack(currentSection.length));
        trackCollection.Add(junction);

        junction.PreviousSectionIndex   = currentSection.index;
        currentSection.NextSectionIndex = junction.index;
        // Create the curved loop junction section
        currentSection = junction.CreateSection(200.0f, true, 90.0f);
        // Create the straight junction section
        TrackSection branch = junction.CreateSection(200.0f, false, 0.0f);

        // Finish the loop
        currentSection = currentSection.CreateNext(400.0f, true, 180.0f);
        // Join it up
        currentSection.NextSectionIndex      = switchSectionCurved.index;
        switchSectionCurved.NextSectionIndex = currentSection.index;

        branch = branch.CreateNext(400, true, 10);
        branch = branch.CreateNext(100, false, 0);
        branch = branch.CreateNext(500, true, -20);
        branch = branch.CreateNext(1000, false, 0);



        //Save it

        TrackLayout trackLayout = TrackLayout.CreateFromTrackCollection(trackCollection);

        AssetDatabase.CreateAsset(trackLayout, "Assets/Resources/DemoTrackLayout.asset");
        AssetDatabase.SaveAssets();

        EditorUtility.FocusProjectWindow();

        Selection.activeObject = trackLayout;
    }