How do i render a Mesh loop?

Hello i am having some trouble trying to render a loop. In Pic1 is what i am trying to achieve but the results i am getting which is in Pic2, does anyone know how to fix this? @Bunny83 @Fattie

-Pic1(What i am trying to achieve)
[76461-capture21.png*_|76461]

-Pic2(The results i am getting)
[76462-capture25.png*_|76462]

Here is my code so you know what i have done(Edit: i accidentally posted the wrong code, but have updated it to the correct one).

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class Catmull : MonoBehaviour {

    public List<Transform> controlPointsList = new List<Transform>();
    private Transform[] objects;
    private Transform[] objectSub_Points;
    public bool isLooping = true;
    public float rotation;
    public GameObject subPoint_Obj;
    public Transform obj;
    public int subPointAmount;
    private Mesh mesh;
    private Vector3[] vertices;

    public int SEGMENT_COUNT;

    void Start()
    {

        int objectCount = controlPointsList.Count * SEGMENT_COUNT;
        
        objectSub_Points = new Transform[objectCount * subPointAmount];
        objects = new Transform[objectCount];
        vertices = new Vector3[objectSub_Points.Length];
        Vector2[] uv = new Vector2[vertices.Length];
        for (int i = 0; i < objectCount; i++)
        {
            objects *= Instantiate(obj);*

for (int c = 0; c <= subPointAmount-1; c++)
{
var subpoint = (GameObject)Instantiate(subPoint_Obj, objects*.position, Quaternion.identity);*

objectSub_Points[c + i * subPointAmount] = subpoint.transform;
subpoint.transform.SetParent(objects*.transform);*
subpoint.transform.localPosition = new Vector3(-c - 1, 0, 0);
}
}
//Mesh
GetComponent().sharedMesh = mesh = new Mesh();
mesh.name = “Procedural Road”;
int[] triangles = new int[(objectCount - 1) * (subPointAmount - 1) * 6];
for (int ti = 0, z = 0; z < subPointAmount - 1; z++)
{
for (int x = 0; x < objectCount - 1; x++, ti += 6)
{
int vi = x * subPointAmount + z;
triangles[ti] = vi;
triangles[ti + 1] = vi + 1;
triangles[ti + 2] = vi + subPointAmount;

triangles[ti + 3] = vi + subPointAmount;
triangles[ti + 4] = vi + 1;
triangles[ti + 5] = vi + subPointAmount + 1;
}
}
mesh.vertices = vertices;
mesh.uv = uv;
mesh.triangles = triangles;
UpdateVertices();
}
void Update()
{
PlaceObjectsOnSpline();
UpdateVertices();
}
void OnDrawGizmos()
{
for (int i = 0; i < controlPointsList.Count; i++)
{

if ((i == 0 || i == controlPointsList.Count - 2 || i == controlPointsList.Count - 1) && !isLooping)
{
continue;
}

DisplayCatmullRomSpline(i);
}
Gizmos.color = Color.white;

for (int i = 0; i < controlPointsList.Count; i++)
{
Gizmos.DrawWireSphere(controlPointsList*.position, 0.3f);*
}
}
Vector3 ReturnCatmullRom(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
{
Vector3 a = 0.5f * (2f * p1);
Vector3 b = 0.5f * (p2 - p0);
Vector3 c = 0.5f * (2f * p0 - 5f * p1 + 4f * p2 - p3);
Vector3 d = 0.5f * (-p0 + 3f * p1 - 3f * p2 + p3);

Vector3 pos = a + (b * t) + (c * t * t) + (d * t * t * t);

return pos;
}

void DisplayCatmullRomSpline(int pos)
{

Vector3 p0 = controlPointsList[ClampListPos(pos - 1)].position;
Vector3 p1 = controlPointsList[pos].position;
Vector3 p2 = controlPointsList[ClampListPos(pos + 1)].position;
Vector3 p3 = controlPointsList[ClampListPos(pos + 2)].position;

Vector3 r = new Vector3((int)rotation, 0, 0);
Vector3 lastPos = Vector3.zero;

for (float i = 0; i < SEGMENT_COUNT; i++)
{
float t = (float)i / SEGMENT_COUNT;

Vector3 newPos = ReturnCatmullRom(t, p0, p1, p2, p3);

if (t == 0)
{
lastPos = newPos;
continue;
}

Gizmos.color = Color.white;
Gizmos.DrawLine(lastPos, newPos);

Gizmos.color = Color.yellow;
var tan = ReturnCatmullRomTangent(t, p0, p1, p2, p3);
Gizmos.DrawLine(newPos, newPos + tan * 3);
Gizmos.DrawSphere(newPos, 0.3f);
lastPos = newPos;
}

Gizmos.DrawLine(lastPos, p2);
}

int ClampListPos(int pos)
{
if (pos < 0)
{
pos = controlPointsList.Count - 1;
}

if (pos > controlPointsList.Count)
{
pos = 1;
}
else if (pos > controlPointsList.Count - 1)
{
pos = 0;
}

return pos;
}
public Vector3 ReturnCatmullRomTangent(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
{
Vector3 b = 0.5f * (p2 - p0);
Vector3 c = (2f * p0 - 5f * p1 + 4f * p2 - p3);
Vector3 d = 1.5f * (-p0 + 3f * p1 - 3f * p2 + p3);
Vector3 tangent = b + c * t + d * t * t;
return tangent.normalized;
}
void PlaceObjectsOnSpline()
{
Vector3 rotate = new Vector3(0, 0, rotation);
for (int i = 0; i < controlPointsList.Count; i++)
{
Vector3 p0 = controlPointsList[ClampListPos(i - 1)].position;
Vector3 p1 = controlPointsList*.position;*
Vector3 p2 = controlPointsList[ClampListPos(i + 1)].position;
Vector3 p3 = controlPointsList[ClampListPos(i + 2)].position;
for (int n = 0; n < SEGMENT_COUNT; n++)
{
float t = (float)n / SEGMENT_COUNT;
Vector3 newPos = ReturnCatmullRom(t, p0, p1, p2, p3);
Vector3 tan = ReturnCatmullRomTangent(t, p0, p1, p2, p3);
Transform inst = objects[i * SEGMENT_COUNT + n];
inst.position = newPos;
inst.rotation = Quaternion.LookRotation(tan);
inst.transform.Rotate(tan + rotate);
}
}
}
private void UpdateVertices()
{
for (int i = 0; i < objectSub_Points.Length; i++)
vertices = transform.InverseTransformPoint(objectSub_Points*.position);
mesh.vertices = vertices;
mesh.RecalculateNormals();
mesh.RecalculateBounds();
_}
}*_

*
*

Well, actually i don’t like to be spammed with tons of comments and questions which request “my help”. It seems you’re still not understanding most of the code and i don’t mean the spline stuff. You should start learning some basic programming and read some material on mesh and geometry generation. UnityAnswer isn’t a place to get a personal tutor that teaches you everything step by step. You already asked something like 5 questions all on the same topic.

I also moved that question into the Help Room.

Anyways…

In the lines 46 - 59 we create the actual triangles. Triangles are generated between vertices by using the proper vertex indices. 3 indices will create one triangle. Each inner loop iteration we create two triangles (one quad). The problem is that we only generate quads in between the points we have generated. That’s why the “count” of each for loop is one less the actual vertex count.

I can’t remember which “direction” was along the spline and which was across, but i guess it was the “x” direction. What you need to do is connect the last point in the array with the first one. For this we need to iterate through all points, not just “objectCount-1”. However this creates a problem since inside the loop we use “vi+1”. For the last points this would throw errors since the index would be out of bounds. We simply need to wrap around the index once we go past the last index so it starts over at “0”. This can be easily done using the modulo operator:

     int[] triangles = new int[(objectCount) * (subPointAmount - 1) * 6];
     int vCount = vertices.Length;
     for (int ti = 0, z = 0; z < subPointAmount - 1; z++)
     {
         for (int x = 0; x < objectCount; x++, ti += 6)
         {
             int vi = x * subPointAmount + z;
             triangles[ti] = vi % vCount;
             triangles[ti + 1] = (vi + 1) % vCount;
             triangles[ti + 2] = (vi + subPointAmount) % vCount;

             triangles[ti + 3] = (vi + subPointAmount) % vCount;
             triangles[ti + 4] = (vi + 1) % vCount;
             triangles[ti + 5] = (vi + subPointAmount + 1) % vCount;
         }
     }

This should create an additional quad between the last point and the first one.