정점을 얻는 메서드를 구현했으니 이제 이용해보자.
새로운 클래스를 선언
에디터 모드에서 실행.
[ExecuteInEditMode()]
public class SplineRoad : MonoBehaviour
{
}
먼저 정점들을 보관해줄 리스트,
얼마나 스플라인을 쪼갤지,
업벡터에 영향을 받을지 안 받을지 정하는 변수를 선언.
private SplineSampler m_splineSampler;
[SerializeField] private int resolution;
[SerializeField] private bool EffectByUpVector;
MeshFilter m_meshFilter;
List<Vector3> m_vertsP1;
List<Vector3> m_vertsP2;
전체 길이가 1이니 1을 resolution만큼 나눈다.
그럼 도로의 양쪽 정점들을 배열에 넣을 수 있다.
void GetVerts()
{
m_vertsP1 = new List<Vector3>();
m_vertsP2 = new List<Vector3>();
float step = 1f / (float)resolution;
for (int i = 0; i <= resolution; i++)
{
float t = step * i;
Math.Round(t, 4);
m_splineSampler.SamplerWidth(t, out Vector3 p1, out Vector3 p2, EffectByUpVector);
m_vertsP1.Add(p1);
m_vertsP2.Add(p2);
}
}
이제 메쉬를 만드는 메서드를 구현해야한다.
메쉬를 간략하게 설명하면 메쉬를 구성하는 정점들을 갖고있는 Vertices와
정점들을 잇는 순서를 나타내는 Triangles로 구성되어있다.
보통 정점은 반 시계 방향으로 잇는다. 이래야 메쉬가 위를 바라보기때문(빛 반사를 표현할 때 필요함)
예를 들자면

이렇게 정점이 4개 있고 옆에 숫자가 정점의 index라고 생각하자.
메쉬는 삼각형 혹은 사각형으로 이루는데 Triangles이므로 삼각형임.
즉 3개씩 끊어서 순서를 주어야한다.

이러한 순서로 정점을 잇는다면 Triangles에는 어떤 값이 들어갈까.
단순하게 생각하면 0-2-3-1-0 이다.
하지만 위에 말한 걸 고려해보자. 3개씩 끊어서 정점을 이어야한다.
즉 0-2-3으로 끊고 3-1-0으로 끊어야한다. 합치면 0-2-3-3-1-0.
이를 메서드에 적용한다.
private void BuildMesh()
{
Mesh m = new Mesh();
List<Vector3> verts = new List<Vector3>();
List<int> tris = new List<int>();
int length = m_vertsP2.Count;
for (int i = 0; i < length; i++)
{
// 현재 인덱스 i와 다음 인덱스 (순환하도록)
int nextIndex = (i + 1) % length;
// 현재 사각형을 구성하는 네 개의 정점
Vector3 p1 = transform.InverseTransformPoint(m_vertsP1[i]);
Vector3 p2 = transform.InverseTransformPoint(m_vertsP2[i]);
Vector3 p3 = transform.InverseTransformPoint(m_vertsP1[nextIndex]);
Vector3 p4 = transform.InverseTransformPoint(m_vertsP2[nextIndex]);
// 정점 추가
int offset = verts.Count; // 현재 추가된 정점 개수 기반으로 오프셋 계산
verts.Add(p1);
verts.Add(p2);
if (nextIndex != 0)
{
verts.Add(p3);
verts.Add(p4);
}
tris.Add(offset + 0);
if (nextIndex != 0)
{
tris.Add(offset + 2);
tris.Add(offset + 3);
tris.Add(offset + 3);
}
tris.Add(offset + 1);
tris.Add(offset + 0);
}
m.SetVertices(verts);
m.SetTriangles(tris, 0);
m_meshFilter.mesh = m;
}
정점 4개만이 아닌 여러개를 이어야하므로 반복문 마지막에는 정점이 마무리지어지도록 조건을 건다.
그리고 결과값이 예상값과 같은지 확인해야하므로 기즈모도 생성.
private void OnDrawGizmos()
{
for (int i = 0; i < m_vertsP1.Count; i++)
{
Handles.SphereHandleCap(0, m_vertsP1[i], Quaternion.identity, 1f, EventType.Repaint);
Handles.SphereHandleCap(0, m_vertsP2[i], Quaternion.identity, 1f, EventType.Repaint);
Gizmos.DrawLine(m_vertsP1[i], m_vertsP2[i]);
}
}

메쉬 필터와 메쉬 렌더러는 필수.

도로 완성.
