Esempio n. 1
0
    public static void GeneratePillars(Vector3[] points, Vector3 startPoint, Vector3 controlPoint, Vector3 endPoint, RoadSegment segment, GameObject bridge, bool simple, PrefabLineCreator customBridge, float startWidthLeft, float startWidthRight, float endWidthLeft, float endWidthRight)
    {
        float   currentDistance   = 0;
        Vector3 lastPosition      = startPoint;
        bool    placedFirstPillar = false;

        if (segment.adaptGapToCustomBridge == true && segment.generateCustomBridge == true)
        {
            PointPackage prefabPoints = customBridge.CalculatePoints();

            for (int i = 0; i < customBridge.transform.GetChild(1).childCount; i++)
            {
                Vector3 currentPosition = Misc.Lerp3CenterHeight(customBridge.transform.GetChild(0).GetChild(0).position, customBridge.transform.GetChild(0).GetChild(1).position, customBridge.transform.GetChild(0).GetChild(2).position, Misc.GetCenter(prefabPoints.startTimes[i], prefabPoints.endTimes[i]));
                // Correct position to extra meshes
                float difference = Mathf.Lerp(startWidthLeft, endWidthLeft, Misc.GetCenter(prefabPoints.startTimes[i], prefabPoints.endTimes[i])) - Mathf.Lerp(startWidthRight, endWidthRight, Misc.GetCenter(prefabPoints.startTimes[i], prefabPoints.endTimes[i]));
                currentPosition += difference * customBridge.transform.GetChild(1).GetChild(i).transform.forward / 2;
                float width = Mathf.Lerp(startWidthLeft + startWidthRight + segment.startRoadWidth * 2, endWidthLeft + endWidthRight + segment.endRoadWidth * 2, Misc.GetCenter(prefabPoints.startTimes[i], prefabPoints.endTimes[i]));
                CreatePillar(bridge.transform, segment.pillarPrefab, currentPosition - new Vector3(0, Mathf.Abs(segment.bridgeSettings.bridgeMesh.GetComponent <MeshFilter>().sharedMesh.bounds.min.y) * segment.bridgeSettings.yScale, 0), segment, -customBridge.transform.GetChild(1).GetChild(i).transform.right, simple, width);
            }
        }
        else
        {
            for (float t = 0; t <= 1; t += 0.01f)
            {
                Vector3 currentPosition = Misc.Lerp3CenterHeight(startPoint, controlPoint, endPoint, t);
                currentDistance = Vector3.Distance(lastPosition, currentPosition);
                Vector3 forward = (currentPosition - lastPosition).normalized;

                if (t == 0)
                {
                    forward = (Misc.Lerp3CenterHeight(startPoint, controlPoint, endPoint, 0.01f) - startPoint).normalized;
                }
                else if (t == 1)
                {
                    forward = (currentPosition - Misc.Lerp3CenterHeight(startPoint, controlPoint, endPoint, 0.99f)).normalized;
                }

                if (placedFirstPillar == false && currentDistance >= segment.pillarPlacementOffset)
                {
                    CreatePillar(bridge.transform, segment.pillarPrefab, currentPosition - new Vector3(0, segment.bridgeSettings.yOffsetFirstStep + segment.bridgeSettings.yOffsetSecondStep, 0), segment, forward, simple, 0);
                    lastPosition      = currentPosition;
                    placedFirstPillar = true;
                }
                else if (placedFirstPillar == true && currentDistance >= segment.pillarGap)
                {
                    CreatePillar(bridge.transform, segment.pillarPrefab, currentPosition - new Vector3(0, segment.bridgeSettings.yOffsetFirstStep + segment.bridgeSettings.yOffsetSecondStep, 0), segment, forward, simple, 0);
                    lastPosition = currentPosition;
                }
            }
        }
    }
Esempio n. 2
0
    private void YModifyPrefabs(GameObject placedPrefab, PointPackage currentPoints, int j)
    {
        if (yModification != PrefabLineCreator.YModification.none)
        {
            Vector3[] vertices    = placedPrefab.GetComponent <MeshFilter>().sharedMesh.vertices;
            float     startHeight = Misc.Lerp3CenterHeight(currentPoints.lerpPoints[Mathf.FloorToInt(currentPoints.startTimes[j]) * 3], currentPoints.lerpPoints[Mathf.FloorToInt(currentPoints.startTimes[j]) * 3 + 1], currentPoints.lerpPoints[Mathf.FloorToInt(currentPoints.startTimes[j]) * 3 + 2], currentPoints.startTimes[j] - Mathf.FloorToInt(currentPoints.startTimes[j])).y;
            float     endHeight   = Misc.Lerp3CenterHeight(currentPoints.lerpPoints[Mathf.FloorToInt(currentPoints.endTimes[j]) * 3], currentPoints.lerpPoints[Mathf.FloorToInt(currentPoints.endTimes[j]) * 3 + 1], currentPoints.lerpPoints[Mathf.FloorToInt(currentPoints.endTimes[j]) * 3 + 2], currentPoints.endTimes[j] - Mathf.FloorToInt(currentPoints.endTimes[j])).y;

            for (var i = 0; i < vertices.Length; i++)
            {
                if (yModification == PrefabLineCreator.YModification.matchTerrain)
                {
                    RaycastHit raycastHit;
                    Vector3    vertexPosition = placedPrefab.transform.rotation * vertices[i];
                    if (Physics.Raycast(placedPrefab.transform.position + (new Vector3(vertexPosition.x * xScale, vertexPosition.y * yScale, vertexPosition.z * zScale)) + new Vector3(0, terrainCheckHeight, 0), Vector3.down, out raycastHit, 100f, ~(1 << LayerMask.NameToLayer("Ignore Mouse Ray") | 1 << LayerMask.NameToLayer("Road") | 1 << LayerMask.NameToLayer("Prefab Line"))))
                    {
                        vertices[i].y += (raycastHit.point.y - placedPrefab.transform.position.y) / yScale;
                    }
                }
                else if (yModification == PrefabLineCreator.YModification.matchCurve)
                {
                    float time = Misc.Remap(vertices[i].x, placedPrefab.GetComponent <MeshFilter>().sharedMesh.bounds.min.x, placedPrefab.GetComponent <MeshFilter>().sharedMesh.bounds.max.x, 0, 1);

                    if (rotationDirection == PrefabLineCreator.RotationDirection.right)
                    {
                        time = 1 - time;
                    }

                    vertices[i].y += (Mathf.Lerp(startHeight, endHeight, time) - placedPrefab.transform.position.y) / yScale;
                }
            }

            Mesh mesh = Instantiate(placedPrefab.GetComponent <MeshFilter>().sharedMesh);
            mesh.vertices = vertices;
            placedPrefab.GetComponent <MeshFilter>().sharedMesh = mesh;
            placedPrefab.GetComponent <MeshFilter>().sharedMesh.RecalculateBounds();

            // Change collider to match
            System.Type type = placedPrefab.GetComponent <Collider>().GetType();
            if (type != null)
            {
                DestroyImmediate(placedPrefab.GetComponent <Collider>());
                placedPrefab.AddComponent(type);
            }
        }
        else if (bridgeSettings.adaptToTerrain == true)
        {
            // Change bottom vertices
            RaycastHit raycastHit;
            Vector3[]  vertices = placedPrefab.GetComponent <MeshFilter>().sharedMesh.vertices;

            if (Physics.Raycast(placedPrefab.transform.position, Vector3.down, out raycastHit, 100, ~(1 << LayerMask.NameToLayer("Ignore Mouse Ray") | 1 << LayerMask.NameToLayer("Road") | 1 << LayerMask.NameToLayer("Prefab Line"))))
            {
                for (int i = 0; i < vertices.Length; i++)
                {
                    if (Mathf.Abs(prefab.GetComponent <MeshFilter>().sharedMesh.vertices[i].y - prefab.GetComponent <MeshFilter>().sharedMesh.bounds.min.y) < 0.0001f)
                    {
                        vertices[i] = new Vector3(vertices[i].x, raycastHit.point.y - (placedPrefab.transform.position.y / yScale) - 0.2f, vertices[i].z);
                    }
                }

                Mesh mesh = Instantiate(placedPrefab.GetComponent <MeshFilter>().sharedMesh);
                mesh.vertices = vertices;
                placedPrefab.GetComponent <MeshFilter>().sharedMesh = mesh;
                placedPrefab.GetComponent <MeshFilter>().sharedMesh.RecalculateBounds();

                // Change collider to match
                System.Type type = placedPrefab.GetComponent <Collider>().GetType();
                if (type != null)
                {
                    DestroyImmediate(placedPrefab.GetComponent <Collider>());
                    placedPrefab.AddComponent(type);
                }
            }
        }
    }
Esempio n. 3
0
    private void BendPrefabs(GameObject placedPrefab, PointPackage currentPoints, int j, float cutoff)
    {
        if (bendObjects == true)
        {
            Mesh      mesh     = GameObject.Instantiate(placedPrefab.GetComponent <MeshFilter>().sharedMesh);
            Vector3[] vertices = mesh.vertices;

            for (var i = 0; i < vertices.Length; i++)
            {
                float distance        = Mathf.Abs(vertices[i].x - mesh.bounds.min.x);
                float distanceCovered = (distance / mesh.bounds.size.x);

                if (rotationDirection == RotationDirection.right)
                {
                    distanceCovered = 1 - distanceCovered;
                }

                float unclampedTime = (distanceCovered) /* * (1 / (cutoff - bridgeOffset)) - bridgeOffset*/;
                float currentTime   = Mathf.Lerp(currentPoints.startTimes[j], currentPoints.endTimes[j], unclampedTime);

                if (bridgeMode == true)
                {
                    Vector3 lerpedPoint = Misc.Lerp3CenterHeight(currentPoints.lerpPoints[0], currentPoints.lerpPoints[1], currentPoints.lerpPoints[2], currentTime);

                    float currentWidth;
                    if (vertices[i].z > 0)
                    {
                        currentWidth = Mathf.Lerp(startWidthLeft, endWidthLeft, currentTime) + mesh.vertices[0].z - bridgeSettings.xOffset;
                    }
                    else
                    {
                        currentWidth = -Mathf.Lerp(startWidthRight, endWidthRight, currentTime) - mesh.vertices[0].z + bridgeSettings.xOffset;
                    }

                    Vector3 right = Misc.MaxVector3;
                    if (currentTime <= 0.99f)
                    {
                        right = Misc.CalculateLeft(lerpedPoint, Misc.Lerp3CenterHeight(currentPoints.lerpPoints[0], currentPoints.lerpPoints[1], currentPoints.lerpPoints[2], currentTime + 0.01f));
                    }
                    else
                    {
                        right = Misc.CalculateLeft(Misc.Lerp3CenterHeight(currentPoints.lerpPoints[0], currentPoints.lerpPoints[1], currentPoints.lerpPoints[2], currentTime - 0.01f), lerpedPoint);
                    }

                    Vector3 rotatedPoint = Quaternion.Euler(0, -(placedPrefab.transform.rotation.eulerAngles.y), 0) * (lerpedPoint - placedPrefab.transform.position + right * (vertices[i].z + currentWidth));
                    float   y            = rotatedPoint.y / yScale;

                    /*if (unclampedTime > 1.1f)
                     * {
                     *  y = -vertices[i].y;
                     * }*/

                    vertices[i] = new Vector3(rotatedPoint.x / xScale, y, rotatedPoint.z / zScale) + new Vector3(0, vertices[i].y, 0);
                }
                else if (distanceCovered > 0 && distanceCovered < 1)
                {
                    int     pointIndex   = Mathf.FloorToInt(currentTime);
                    Vector3 lerpedPoint  = Misc.Lerp3CenterHeight(currentPoints.lerpPoints[pointIndex * 3], currentPoints.lerpPoints[pointIndex * 3 + 1], currentPoints.lerpPoints[pointIndex * 3 + 2], currentTime - pointIndex);
                    float   y            = vertices[i].y;
                    Vector3 rotatedPoint = Quaternion.Euler(0, -(placedPrefab.transform.rotation.eulerAngles.y), 0) * (lerpedPoint - placedPrefab.transform.position);
                    vertices[i]  += new Vector3(rotatedPoint.x / xScale, rotatedPoint.y / yScale, rotatedPoint.z / zScale) - new Vector3(vertices[i].x, 0, 0);
                    vertices[i].y = y;
                }
            }

            mesh.vertices = vertices;
            mesh.RecalculateBounds();
            placedPrefab.GetComponent <MeshFilter>().sharedMesh = mesh;

            // Change collider to match
            System.Type type = placedPrefab.GetComponent <Collider>().GetType();
            if (type != null)
            {
                DestroyImmediate(placedPrefab.GetComponent <Collider>());
                placedPrefab.AddComponent(type);
            }
        }
    }
Esempio n. 4
0
    public void PlacePrefabs()
    {
        if (prefab == null)
        {
            prefab = (GameObject)settings.FindProperty("defaultPrefabLinePrefab").objectReferenceValue;
        }

        for (int i = transform.GetChild(1).childCount - 1; i >= 0; i--)
        {
            DestroyImmediate(transform.GetChild(1).GetChild(i).gameObject);
        }

        if (fillGap == true && rotationDirection != PrefabLineCreator.RotationDirection.left && rotationDirection != PrefabLineCreator.RotationDirection.right)
        {
            rotationDirection = PrefabLineCreator.RotationDirection.left;
        }

        if (spacing == -1)
        {
            spacing = prefab.GetComponent <MeshFilter>().sharedMesh.bounds.extents.x * 2 * xScale;
        }

        if (transform.GetChild(0).childCount > 2)
        {
            PointPackage currentPoints = CalculatePoints();
            for (int j = 0; j < currentPoints.prefabPoints.Length; j++)
            {
                float cutoff = 1;
                if (j == currentPoints.prefabPoints.Length - 1)
                {
                    cutoff = (bridgeSettings.sections + bridgeOffset) % 1.0f;

                    if (cutoff == 0)
                    {
                        cutoff = 1;
                    }
                }

                GameObject placedPrefab;

                if (j == 0 && startPrefab != null)
                {
                    placedPrefab = Instantiate(startPrefab);
                }
                else if (j == currentPoints.prefabPoints.Length - 1 && endPrefab != null)
                {
                    placedPrefab = Instantiate(endPrefab);
                }
                else
                {
                    placedPrefab = Instantiate(prefab);
                }

                placedPrefab.transform.SetParent(transform.GetChild(1));
                placedPrefab.name = "Prefab";
                placedPrefab.transform.localScale = new Vector3(xScale, yScale, zScale);

                if (placedPrefab.layer == LayerMask.NameToLayer("Default"))
                {
                    placedPrefab.layer = LayerMask.NameToLayer("Prefab Line");
                }

                if (settings.FindProperty("hideNonEditableChildren").boolValue == true)
                {
                    placedPrefab.hideFlags = HideFlags.HideInHierarchy;
                }
                else
                {
                    placedPrefab.hideFlags = HideFlags.NotEditable;
                }

                Vector3 startPoint = Misc.Lerp3CenterHeight(currentPoints.lerpPoints[Mathf.FloorToInt(currentPoints.startTimes[j]) * 3], currentPoints.lerpPoints[Mathf.FloorToInt(currentPoints.startTimes[j]) * 3 + 1], currentPoints.lerpPoints[Mathf.FloorToInt(currentPoints.startTimes[j]) * 3 + 2], currentPoints.startTimes[j] - Mathf.FloorToInt(currentPoints.startTimes[j]));
                Vector3 endPoint   = Misc.Lerp3CenterHeight(currentPoints.lerpPoints[Mathf.FloorToInt(currentPoints.endTimes[j]) * 3], currentPoints.lerpPoints[Mathf.FloorToInt(currentPoints.endTimes[j]) * 3 + 1], currentPoints.lerpPoints[Mathf.FloorToInt(currentPoints.endTimes[j]) * 3 + 2], currentPoints.endTimes[j] - Mathf.FloorToInt(currentPoints.endTimes[j]));

                if (bendObjects == true)
                {
                    placedPrefab.transform.position = Misc.GetCenter(startPoint, endPoint);
                }
                else
                {
                    placedPrefab.transform.position = currentPoints.prefabPoints[j];
                }

                Vector3 left    = Misc.CalculateLeft(startPoint, endPoint);
                Vector3 forward = new Vector3(left.z, 0, -left.x);

                RotatePrefabs(placedPrefab, forward, left);
                BendPrefabs(placedPrefab, currentPoints, j, cutoff);
                YModifyPrefabs(placedPrefab, currentPoints, j);
                FillGapsBetweenPrefabs(placedPrefab, j);
            }
        }
    }
Esempio n. 5
0
    public void PlacePrefabs()
    {
        if (prefab == null)
        {
            prefab = Resources.Load("Prefabs/Low Poly/Concrete Barrier") as GameObject;
        }

        for (int i = transform.GetChild(1).childCount - 1; i >= 0; i--)
        {
            DestroyImmediate(transform.GetChild(1).GetChild(i).gameObject);
        }

        if (fillGap == true && rotationDirection != PrefabLineCreator.RotationDirection.left && rotationDirection != PrefabLineCreator.RotationDirection.right)
        {
            rotationDirection = PrefabLineCreator.RotationDirection.left;
        }

        if (transform.GetChild(0).childCount > 2)
        {
            PointPackage currentPoints = CalculatePoints();
            for (int j = 0; j < currentPoints.prefabPoints.Length; j++)
            {
                GameObject placedPrefab;

                if (j == 0 && startPrefab != null)
                {
                    placedPrefab = Instantiate(startPrefab);
                }
                else if (j == currentPoints.prefabPoints.Length - 1 && endPrefab != null)
                {
                    placedPrefab = Instantiate(endPrefab);
                }
                else
                {
                    placedPrefab = Instantiate(prefab);
                }

                placedPrefab.transform.SetParent(transform.GetChild(1));
                placedPrefab.transform.position = Misc.GetCenter(currentPoints.startPoints[j], currentPoints.endPoints[j]);
                placedPrefab.name  = "Prefab";
                placedPrefab.layer = globalSettings.roadLayer;
                placedPrefab.transform.localScale = new Vector3(scale, scale, scale);
                Vector3 left    = Misc.CalculateLeft(currentPoints.startPoints[j], currentPoints.endPoints[j]);
                Vector3 forward = new Vector3(left.z, 0, -left.x);

                if (rotateAlongCurve == true)
                {
                    if (rotationDirection == PrefabLineCreator.RotationDirection.forward)
                    {
                        placedPrefab.transform.rotation = Quaternion.Euler(Quaternion.LookRotation(forward).eulerAngles.x, Quaternion.LookRotation(forward).eulerAngles.y + Random.Range(-yRotationRandomization / 2, yRotationRandomization / 2), Quaternion.LookRotation(forward).eulerAngles.z);
                    }
                    else if (rotationDirection == PrefabLineCreator.RotationDirection.backward)
                    {
                        placedPrefab.transform.rotation = Quaternion.Euler(Quaternion.LookRotation(-forward).eulerAngles.x, Quaternion.LookRotation(-forward).eulerAngles.y + Random.Range(-yRotationRandomization / 2, yRotationRandomization / 2), Quaternion.LookRotation(-forward).eulerAngles.z);
                    }
                    else if (rotationDirection == PrefabLineCreator.RotationDirection.left)
                    {
                        placedPrefab.transform.rotation = Quaternion.Euler(Quaternion.LookRotation(left).eulerAngles.x, Quaternion.LookRotation(left).eulerAngles.y + Random.Range(-yRotationRandomization / 2, yRotationRandomization / 2), Quaternion.LookRotation(left).eulerAngles.z);
                    }
                    else if (rotationDirection == PrefabLineCreator.RotationDirection.right)
                    {
                        placedPrefab.transform.rotation = Quaternion.Euler(Quaternion.LookRotation(-left).eulerAngles.x, Quaternion.LookRotation(-left).eulerAngles.y + Random.Range(-yRotationRandomization / 2, yRotationRandomization / 2), Quaternion.LookRotation(-left).eulerAngles.z);
                    }
                }

                if (bendObjects == true)
                {
                    Mesh      mesh             = GameObject.Instantiate(placedPrefab.GetComponent <MeshFilter>().sharedMesh);
                    Vector3[] vertices         = mesh.vertices;
                    float     distanceToChange = Mathf.Abs((Quaternion.Euler(0, -placedPrefab.transform.rotation.eulerAngles.y, 0) * placedPrefab.transform.position).z - (Quaternion.Euler(0, -placedPrefab.transform.rotation.eulerAngles.y, 0) * currentPoints.prefabPoints[j]).z);

                    Vector3 controlPoint;
                    if (currentPoints.rotateTowardsLeft[j] == false)
                    {
                        distanceToChange = -distanceToChange;
                    }

                    controlPoint = mesh.bounds.center + new Vector3(0, 0, distanceToChange * 4);

                    for (var i = 0; i < vertices.Length; i++)
                    {
                        float   distance        = Mathf.Abs(vertices[i].x - mesh.bounds.min.x);
                        float   distanceCovered = (distance / mesh.bounds.size.x);
                        Vector3 lerpedPoint     = Misc.Lerp3(new Vector3(-mesh.bounds.extents.x, 0, 0), controlPoint, new Vector3(mesh.bounds.extents.x, 0, 0), distanceCovered);
                        vertices[i].z = vertices[i].z - (lerpedPoint).z;
                    }

                    mesh.vertices = vertices;
                    mesh.RecalculateBounds();
                    placedPrefab.GetComponent <MeshFilter>().sharedMesh = mesh;

                    // Change collider to match
                    System.Type type = placedPrefab.GetComponent <Collider>().GetType();
                    if (type != null)
                    {
                        DestroyImmediate(placedPrefab.GetComponent <Collider>());
                        placedPrefab.AddComponent(type);
                    }
                }

                if (yModification != PrefabLineCreator.YModification.none)
                {
                    Vector3[] vertices    = placedPrefab.GetComponent <MeshFilter>().sharedMesh.vertices;
                    float     startHeight = currentPoints.startPoints[j].y;
                    float     endHeight   = currentPoints.endPoints[j].y;

                    for (var i = 0; i < vertices.Length; i++)
                    {
                        if (yModification == PrefabLineCreator.YModification.matchTerrain)
                        {
                            RaycastHit raycastHit;
                            if (Physics.Raycast(placedPrefab.transform.position + (placedPrefab.transform.rotation * vertices[i] * scale) + new Vector3(0, terrainCheckHeight, 0), Vector3.down, out raycastHit, 100f, ~(1 << globalSettings.ignoreMouseRayLayer | 1 << globalSettings.roadLayer)))
                            {
                                vertices[i].y += (raycastHit.point.y - placedPrefab.transform.position.y) / scale;
                            }
                        }
                        else if (yModification == PrefabLineCreator.YModification.matchCurve)
                        {
                            float time = Misc.Remap(vertices[i].x, placedPrefab.GetComponent <MeshFilter>().sharedMesh.bounds.min.x, placedPrefab.GetComponent <MeshFilter>().sharedMesh.bounds.max.x, 0, 1);

                            if (rotationDirection == PrefabLineCreator.RotationDirection.right)
                            {
                                time = 1 - time;
                            }

                            vertices[i].y += (Mathf.Lerp(startHeight, endHeight, time) - placedPrefab.transform.position.y) / scale;
                        }
                    }

                    Mesh mesh = Instantiate(placedPrefab.GetComponent <MeshFilter>().sharedMesh);
                    mesh.vertices = vertices;
                    placedPrefab.GetComponent <MeshFilter>().sharedMesh = mesh;
                    placedPrefab.GetComponent <MeshFilter>().sharedMesh.RecalculateBounds();

                    // Change collider to match
                    System.Type type = placedPrefab.GetComponent <Collider>().GetType();
                    if (type != null)
                    {
                        DestroyImmediate(placedPrefab.GetComponent <Collider>());
                        placedPrefab.AddComponent(type);
                    }
                }

                if (fillGap == true && j > 0)
                {
                    // Add last vertices
                    List <Vector3> lastVertexPositions = new List <Vector3>();
                    Vector3[]      lastVertices        = transform.GetChild(1).GetChild(j - 1).GetComponent <MeshFilter>().sharedMesh.vertices;
                    for (int i = 0; i < lastVertices.Length; i++)
                    {
                        if (Mathf.Abs(lastVertices[i].x - GetMaxX()) < 0.001f)
                        {
                            lastVertexPositions.Add((transform.GetChild(1).GetChild(j - 1).transform.rotation *(scale * lastVertices[i])) + transform.GetChild(1).GetChild(j - 1).transform.position);
                        }
                    }

                    // Move current vertices to last ones
                    Mesh      mesh     = Instantiate(placedPrefab.GetComponent <MeshFilter>().sharedMesh);
                    Vector3[] vertices = mesh.vertices;
                    for (int i = 0; i < vertices.Length; i++)
                    {
                        if (Mathf.Abs(vertices[i].x - GetMinX()) < 0.001f)
                        {
                            Vector3 nearestVertex   = Vector3.zero;
                            float   currentDistance = float.MaxValue;

                            for (int k = 0; k < lastVertexPositions.Count; k++)
                            {
                                float localZ      = (Quaternion.Euler(0, -(transform.GetChild(1).GetChild(j - 1).transform.rotation.eulerAngles.y), 0) * (lastVertexPositions[k] - transform.GetChild(1).GetChild(j - 1).transform.position)).z;
                                float zDifference = Mathf.Abs(localZ - (vertices[i].z * scale));
                                if (zDifference < 0.001f)
                                {
                                    if (yModification == PrefabLineCreator.YModification.none)
                                    {
                                        if (Mathf.Abs(lastVertexPositions[k].y - ((vertices[i].y * scale) + placedPrefab.transform.position.y)) < currentDistance)
                                        {
                                            nearestVertex   = lastVertexPositions[k];
                                            currentDistance = Mathf.Abs(lastVertexPositions[k].y - ((vertices[i].y * scale) + placedPrefab.transform.position.y));
                                        }
                                    }
                                    else
                                    {
                                        float calculatedDistance = Vector3.Distance(lastVertexPositions[k], (placedPrefab.transform.rotation * (scale * vertices[i])) + placedPrefab.transform.position);

                                        if (calculatedDistance < currentDistance)
                                        {
                                            currentDistance = calculatedDistance;
                                            nearestVertex   = lastVertexPositions[k];
                                        }
                                    }
                                }
                            }

                            if (nearestVertex != Vector3.zero)
                            {
                                float scaleModifier = 1 / scale;
                                vertices[i] = Quaternion.Euler(0, -placedPrefab.transform.rotation.eulerAngles.y, 0) * (nearestVertex - placedPrefab.transform.position) * scaleModifier;
                            }
                        }
                    }
                    mesh.vertices = vertices;
                    placedPrefab.GetComponent <MeshFilter>().sharedMesh = mesh;
                    placedPrefab.GetComponent <MeshFilter>().sharedMesh.RecalculateBounds();

                    // Change collider to match
                    System.Type type = placedPrefab.GetComponent <Collider>().GetType();
                    if (type != null)
                    {
                        DestroyImmediate(placedPrefab.GetComponent <Collider>());
                        placedPrefab.AddComponent(type);
                    }
                }
            }
        }
    }
    public void PlacePrefabs()
    {
        for (int i = prefabCreator.transform.GetChild(1).childCount - 1; i >= 0; i--)
        {
            DestroyImmediate(prefabCreator.transform.GetChild(1).GetChild(i).gameObject);
        }

        if (prefabCreator.transform.GetChild(0).childCount > 2)
        {
            PointPackage currentPoints = CalculatePoints(Misc.GetPrefabOffset(prefabCreator.prefab, prefabCreator.scale, prefabCreator.globalSettings.pointSize * prefabCreator.scale));
            for (int j = 0; j < currentPoints.prefabPoints.Length; j++)
            {
                GameObject prefab = Instantiate(prefabCreator.prefab);
                prefab.transform.SetParent(prefabCreator.transform.GetChild(1));
                prefab.transform.position = currentPoints.prefabPoints[j];
                prefab.name  = "Prefab";
                prefab.layer = prefabCreator.globalSettings.roadLayer;
                prefab.transform.localScale = new Vector3(prefabCreator.scale, prefabCreator.scale, prefabCreator.scale);
                Vector3 left    = Misc.CalculateLeft(currentPoints.startPoints[j], currentPoints.endPoints[j]);
                Vector3 forward = new Vector3(left.z, 0, -left.x);

                if (prefabCreator.rotateAlongCurve == true)
                {
                    if (prefabCreator.rotationDirection == PrefabLineCreator.RotationDirection.forward)
                    {
                        prefab.transform.rotation = Quaternion.LookRotation(forward);
                    }
                    else if (prefabCreator.rotationDirection == PrefabLineCreator.RotationDirection.backward)
                    {
                        prefab.transform.rotation = Quaternion.LookRotation(-forward);
                    }
                    else if (prefabCreator.rotationDirection == PrefabLineCreator.RotationDirection.left)
                    {
                        prefab.transform.rotation = Quaternion.LookRotation(left);
                    }
                    else if (prefabCreator.rotationDirection == PrefabLineCreator.RotationDirection.right)
                    {
                        prefab.transform.rotation = Quaternion.LookRotation(-left);
                    }
                    else if (prefabCreator.rotationDirection == PrefabLineCreator.RotationDirection.randomY)
                    {
                        prefab.transform.rotation = Quaternion.Euler(0, Random.Range(0, 360), 0);
                    }
                }

                if (prefabCreator.bendObjects == true)
                {
                    Mesh      mesh     = GameObject.Instantiate(prefabCreator.prefab.GetComponent <MeshFilter>().sharedMesh);
                    Vector3[] vertices = mesh.vertices;

                    // Calculate distance to change
                    Vector3 center           = Misc.GetCenter(currentPoints.startPoints[j], currentPoints.endPoints[j]);
                    float   distanceToChange = Vector3.Distance(center, currentPoints.prefabPoints[j]);

                    Vector3 controlPoint;
                    float   distanceToChangeMultiplied = distanceToChange * prefabCreator.bendMultiplier;
                    if (currentPoints.rotateTowardsLeft[j] == false)
                    {
                        distanceToChangeMultiplied = -distanceToChangeMultiplied;
                    }

                    if (prefabCreator.rotationDirection == PrefabLineCreator.RotationDirection.right)
                    {
                        distanceToChangeMultiplied = -distanceToChangeMultiplied;
                    }

                    controlPoint = mesh.bounds.center + new Vector3(0, 0, distanceToChangeMultiplied);

                    for (var i = 0; i < vertices.Length; i++)
                    {
                        float   distance        = Mathf.Abs(vertices[i].x - mesh.bounds.min.x);
                        float   distanceCovered = (distance / mesh.bounds.size.x);
                        Vector3 lerpedPoint     = Misc.Lerp3(new Vector3(-mesh.bounds.extents.x, 0, 0), controlPoint, new Vector3(mesh.bounds.extents.x, 0, 0), distanceCovered);
                        vertices[i].z = vertices[i].z - (lerpedPoint).z;
                    }

                    mesh.vertices = vertices;
                    mesh.RecalculateBounds();
                    prefab.GetComponent <MeshFilter>().sharedMesh = mesh;
                }

                if (prefabCreator.fillGap == true && j > 0)
                {
                    // Add last vertices
                    List <Vector3> lastVertexPositions = new List <Vector3>();
                    Vector3[]      lastVertices        = prefabCreator.transform.GetChild(1).GetChild(j - 1).GetComponent <MeshFilter>().sharedMesh.vertices;
                    for (int i = 0; i < lastVertices.Length; i++)
                    {
                        if (lastVertices[i].x == GetMaxX())
                        {
                            lastVertexPositions.Add((prefabCreator.transform.GetChild(1).GetChild(j - 1).transform.rotation *lastVertices[i]) + prefabCreator.transform.GetChild(1).GetChild(j - 1).transform.position);
                        }
                    }

                    // Move current vertices to last ones
                    Mesh      mesh     = GameObject.Instantiate(prefab.GetComponent <MeshFilter>().sharedMesh);
                    Vector3[] vertices = mesh.vertices;
                    for (int i = 0; i < mesh.vertices.Length; i++)
                    {
                        if (vertices[i].x == GetMinX())
                        {
                            Vector3 nearestVertex   = Vector3.zero;
                            float   currentDistance = float.MaxValue;

                            for (int k = 0; k < lastVertexPositions.Count; k++)
                            {
                                float localZ      = (Quaternion.Euler(0, -(prefabCreator.transform.GetChild(1).GetChild(j - 1).transform.rotation.eulerAngles.y), 0) * (lastVertexPositions[k] - prefabCreator.transform.GetChild(1).GetChild(j - 1).transform.position)).z;
                                float zDifference = Mathf.Abs(localZ - vertices[i].z);
                                if (zDifference < 0.001f)
                                {
                                    float calculatedDistance = Vector3.Distance(lastVertexPositions[k], (prefab.transform.rotation * vertices[i]) + prefab.transform.position);
                                    if (calculatedDistance < currentDistance)
                                    {
                                        currentDistance = calculatedDistance;
                                        nearestVertex   = lastVertexPositions[k];
                                    }
                                }
                            }

                            vertices[i] = Quaternion.Euler(0, -(prefab.transform.rotation.eulerAngles.y), 0) * (nearestVertex - prefab.transform.position);
                        }
                    }
                    mesh.vertices = vertices;
                    prefab.GetComponent <MeshFilter>().sharedMesh = mesh;
                    prefab.GetComponent <MeshFilter>().sharedMesh.RecalculateBounds();

                    // Change collider to match
                    System.Type type = prefab.GetComponent <Collider>().GetType();
                    if (type != null)
                    {
                        DestroyImmediate(prefab.GetComponent <Collider>());
                        prefab.AddComponent(type);
                    }
                }
            }
        }
    }