Unity 구(Sphere)를 직접 만들어보자 🏐
Unity에서 기본적으로 제공하는 3D 오브젝트중 Sphere를 만들었을때 WireFrame을 보면 이런 삼각형들로 이루어져있다.

사실 컴퓨터로 표현되는 3D모델들은 모두 폴리곤이라는 삼각형들이 모여 하나의 물체를 이루기 때문에 구 또한 삼각형들의 집함으로 이루어져있다는걸 알 수 있다. 이 폴리곤들이 촘촘하면 촘촘 할 수록 더 매끈한 구가 되겠지만 그만큼 연산량은 많아질것이다.

넓은의미로 모두 구 이다.
구를 만들기 위해 차근차근 [ 평면 -> 정육면체 -> 구체 ] 순으로 만들어 볼 생각이다.
평면 만들기
평면을 만들기 위해 생성자로 3개의 인자를 전달받을 껀데, 정점배열들을 이용해서 면을 채워줄 mesh, 정점들의 갯수를 결정하는 resolution, 면이 중심으로부터 생성될 방향을 결정할 localUp을 정의해준다.
public class MeshFace
{
	private Mesh mesh;
	private int resolution;
	private Vector3 localUp;
	private Vector3 axisA;
	private Vector3 axisB;
    public MeshFace(Mesh mesh, int resolution, Vector3 localUp)
    {
        this.mesh = mesh;
        this.resolution = resolution;
        this.localUp = localUp;
        axisA = new Vector3(localUp.y, localUp.z, localUp.x);
        axisB = Vector3.Cross(localUp, axisA);
    }
}axisA와 axisB는 localUp벡터를 y축방향 벡터라고 생각한다면 각각 x, z 벡터라 할 수 있겠다.
화면에 직접 보이도록하기 위해서는 Mesh라는 컴포넌트를 이용해야하는데, Mesh에게 정점의 위치정보 mesh.vertices와 정점을 그리는 순서를 담은 mesh.triangles를 정해주면 그에따라 면을 그려주게 된다. https://docs.unity3d.com/kr/530/ScriptReference/Mesh.html
mesh.vertices 
mesh.triangles그렇다면 이제 만들어야할것은 vertices와 triangles에 들어가야할 배열들을 계산해줘야할듯 싶다.
먼저 vertices, 정점의 갯수는 resolution의 값에 따라 일괄적으로 줄여주거나 늘려줄것이다. resolution = 5 일경우 가로 5개 x 세로 5개 총 25개의 정점을 만들도록 할 것이다.

Vector3[] vertices = new Vector3[resolution * resolution];다음 triangles,
resolution = 5 일경우 (5 - 1)개의 가로사각형 (5-1)개의 세로사각형 = 16개의 사각형을 만들수 있을것이고, 사각형1개는 2개의 삼각형으로 이루어져있고, 이 삼각형은 3개의 정점으로 이루어져 있다.

int[] triangles = new int[(resolution - 1) * (resolution - 1) * 2 * 3];이제 vertices와 triangles의 값들을 채워보자
public void CreateMesh()
{
    Vector3[] vertices = new Vector3[resolution * resolution];
    int[] triangles = new int[(resolution - 1) * (resolution - 1) * 2 * 3];
    int triIndex = 0;
    for (int y = 0; y < resolution; y++)
    {
        for (int x = 0; x < resolution; x++)
        {
            int vertexIndex = x + y * resolution;
            Vector2 percent = new Vector2(x, y) / (resolution - 1); // 0~1로 노멀라이즈
            Vector3 pointOnUnitCube = localUp + (percent.x - .5f) * 2 * axisA + (percent.y - .5f) * 2 * axisB;
            Vector3 pointOnUnitSphere = pointOnUnitCube.normalized;
            vertices[vertexIndex] = pointOnUnitCube;
            if (x != resolution - 1 && y != resolution - 1)
            {
                triangles[triIndex] = vertexIndex;
                triangles[triIndex + 1] = vertexIndex + resolution + 1;
                triangles[triIndex + 2] = vertexIndex + resolution;
                triangles[triIndex + 3] = vertexIndex;
                triangles[triIndex + 4] = vertexIndex + 1;
                triangles[triIndex + 5] = vertexIndex + resolution + 1;
                triIndex += 6;
            }
        }
    }
    mesh.Clear();
    mesh.vertices = vertices;
    mesh.triangles = triangles;
    mesh.RecalculateNormals();
}코드를 하나하나 봐보자면
int vertexIndex = x + y * resolution;
Vector2 percent = new Vector2(x, y) / (resolution - 1); // 0~1로 노멀라이즈
Vector3 pointOnUnitCube = (percent.x - 0.5f) * 2 * axisA + (percent.y - 0.5f) * 2 * axisB + localUp; resolution = 5라고 가정하면,
percent : x, y가 (0,0) 일때부터 (4,4) 까지의 값을 가질텐데 그 값을 4로 나눠주기 때문에 (0,0) ~ (1,1) 의 값으로 노멀라이즈 해주게된다.
pointOnUnitCube : x랑 y의 값을 - 0.5 만큼 뺀 값을 2만큼 곱해주어, (0,0) ~ (1,1)의 범위의 값들이 (-1,-1) ~ (1,1)의 값으로 바뀔것이고 이에 localUp 벡터만큼 더해주면 다음과같은 평면의 벡터들을 구할 수 있을것이다.

triangles[ ] : 아래 그림의 각 숫자가 vertexIndex인데 삼각형의 정점을 시계방향순으로 써보면 vertexIndex, vertexIndex + 1, vertexIndex + resolution 이라는 하단 삼각형과 vertexIndex, vertexIndex + 1, vertexIndex + resolution + 1 이라는 상단 삼각형의 순서를 구할 수 있다.

이렇게 vertices와 triangles를 구했으면 mesh에 넣어주면된다.
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles
mesh.RecalculateNormals();테스트를 해보자
using UnityEngine;
public class Sphere : MonoBehaviour
{
    [Range(2, 256)]
    public int resolution = 5;
    private void OnValidate()
    {
        TEST();
    }
    void TEST()
    {
        GameObject meshObj = new GameObject("mesh");
        meshObj.transform.parent = transform;
        meshObj.AddComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("Standard"));
        MeshFilter meshFilter = meshObj.AddComponent<MeshFilter>();
        meshFilter.sharedMesh = new Mesh();
        MeshFace face = new MeshFace(meshFilter.sharedMesh, resolution, Vector3.up);
        face.CreateMesh();
    }
}
GOOD!
정육면체 만들기
평면을 만들었다면 정육면체를 만드는건 너무나 쉽다. 평면을 6개만 만들면 되니까.
Vector3[] directions = { Vector3.up, Vector3.down, Vector3.left, Vector3.right, Vector3.forward, Vector3.back };
for (int i = 0; i < 6; i++)
{
    if (meshFilters[i] == null)
    {
        GameObject meshObj = new GameObject("mesh");
        meshObj.transform.parent = transform;
        meshObj.AddComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("Standard"));
        meshFilters[i] = meshObj.AddComponent<MeshFilter>();
        meshFilters[i].sharedMesh = new Mesh();
    }
    terrainFaces[i] = new MeshFace(meshFilters[i].sharedMesh, resolution, directions[i]);
}
EASY~
마지막으로 구체 만들기
고등학교 수학시간에 구를 배울때 구의 정의를 생각해보면 3차원에서 한 중점으로부터 거리가 같은 점들의 집합으로 배웠었다. 그렇다면 다시 돌아가서 아까 평면을 만들었을때를 봐보자

저 평면을 이루는 벡터는 중점으로부터 거리가 정점마다 모두 다를 것이다. 이 벡터들을 방향은 같고 크기만 동일하게 노멀라이즈 해준다면

마치 이런모양으로 바뀔것이다.
Vector3 pointOnUnitCube = localUp + (percent.x - .5f) * 2 * axisA + (percent.y - .5f) * 2 * axisB;
Vector3 pointOnUnitSphere = pointOnUnitCube.normalized; // 노멀라이즈
vertices[vertexIndex] = pointOnUnitSphere; // 노멀라이즈한 값을 넣어줌
GREAT!
Sphere.cs의 코드를 좀더 깔끔하게 다듬어 보면
using UnityEngine;
public class Sphere : MonoBehaviour
{
    [Range(2, 256)]
    public int resolution = 10;
    [SerializeField, HideInInspector]
    MeshFilter[] meshFilters;
    MeshFace[] terrainFaces;
    private void OnValidate()
    {
        Initialize();
        GenerateMesh();
    }
    void Initialize()
    {
        if (meshFilters == null || meshFilters.Length == 0)
        {
            meshFilters = new MeshFilter[6];
        }
        terrainFaces = new MeshFace[6];
        Vector3[] directions = { Vector3.up, Vector3.down, Vector3.left, Vector3.right, Vector3.forward, Vector3.back };
        for (int i = 0; i < 6; i++)
        {
            if (meshFilters[i] == null)
            {
                GameObject meshObj = new GameObject("mesh");
                meshObj.transform.parent = transform;
                meshObj.AddComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("Standard"));
                meshFilters[i] = meshObj.AddComponent<MeshFilter>();
                meshFilters[i].sharedMesh = new Mesh();
            }
            terrainFaces[i] = new MeshFace(meshFilters[i].sharedMesh, resolution, directions[i]);
        }
    }
    void GenerateMesh()
    {
        foreach (MeshFace face in terrainFaces)
        {
            face.CreateMesh();
        }
    }
}Author And Source
이 문제에 관하여(Unity 구(Sphere)를 직접 만들어보자 🏐), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@dev_juicy/Unity-직접-구Sphere를-만들어보자저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)