# 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)

-Pic2(The results i am getting)

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[i] = Instantiate(obj);
for (int c = 0; c <= subPointAmount-1; c++)
{
var subpoint = (GameObject)Instantiate(subPoint_Obj, objects[i].position, Quaternion.identity);
objectSub_Points[c + i * subPointAmount] = subpoint.transform;
subpoint.transform.SetParent(objects[i].transform);
subpoint.transform.localPosition = new Vector3(-c - 1, 0, 0);
}
}
//Mesh
GetComponent<MeshFilter>().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[i].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[i].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[i] = transform.InverseTransformPoint(objectSub_Points[i].position);
mesh.vertices = vertices;
mesh.RecalculateNormals();
mesh.RecalculateBounds();
}
}
```

### People who like this

Hey @Bunny83 can you please help me out, i have been on this subject for more than 2 days i would appreciate it if you did.

**Answer** by Bunny83
·
Aug 20, 2016 at 03:44 PM

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.

Thanks, and sorry for the spamming, you we're just an alternative however since i was getting no replies on my Questions i did start mentioning you in new threads a lot more since you're the only one that answers my questions on Mesh.

I already knew how to do the modulo stuff but me implementing into the triangles i did not know how to do, nor knowing the fundamentals on triangles, if you do know anything on Mesh Geometry in E-books or in tutorials that would be great, because i have not found much anything on Mesh Geometry because most of the search results(Google) i get are just crap, i was looking for Mesh Geometry for around 1 1/2 months but only found so little. Anyway thanks again.

### Unity Answers is in Read-Only mode

Unity Answers content will be migrated to a new Community platform and we are aiming to launch a public beta by June 9. **Please note, Unity Answers is now in read-only so we can prepare for the final data migration.**

For more information and updates, please read our full announcement thread in the Unity Forum.