根据顶点创建Cube Sphere

这篇博客详细介绍了如何在Unity中通过调整顶点坐标,将一个立方体转换成一个平滑的球体,这一过程对于3D建模和游戏开发中的图形渲染具有实际应用价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

public class CreateModelByVertices : MonoBehaviour
{
    public int _resolution;

    private GameObject _Root;
    private MeshData[] _meshDatas;
    private List<MeshFilter> _meshFilterList = new List<MeshFilter>();

    [ContextMenu("生成Cube")]
    public void CreateCube()
    {
        if (_Root != null)
            DestroyImmediate(_Root);
        _meshFilterList.Clear();

        _meshDatas = GenerateFaces(_resolution);

        _Root = new GameObject("Go");

        foreach (var meshData in _meshDatas)
        {
            GameObject faceGo = new GameObject("face");
            faceGo.transform.SetParent(_Root.transform);
            var meshFilter = faceGo.AddComponent<MeshFilter>();
            Mesh mesh = new Mesh();
            mesh.vertices = meshData.vertices;
            mesh.triangles = meshData.triangles;

            meshFilter.mesh = mesh;

            var meshRenderer = faceGo.AddComponent<MeshRenderer>();
            meshRenderer.material = new Material(Shader.Find("Standard"));

            _meshFilterList.Add(meshFilter);
        }
    }

    [ContextMenu("变球")]
    public void CreateSphere()
    {
        BuildSphere();
    }

    void BuildSphere()
    {
        for (int i = 0; i < _meshDatas.Length; i++)
        {
            StartCoroutine(ModifyVertices(_meshFilterList[i], _meshDatas[i]));
        }
    }

    private void BuildOneFace(MeshFilter meshFilter, MeshData meshData)
    {
        Mesh mesh = new Mesh();
        mesh.vertices = meshData.vertices;
        mesh.triangles = meshData.triangles;

        meshFilter.mesh = mesh;
    }

    IEnumerator ModifyVertices(MeshFilter meshFilter, MeshData meshData)
    {
        for (int i = 0; i < meshData.vertices.Length; i++)
        {
            meshData.vertices[i] = PointOnCubeToPointOnSphere(meshData.vertices[i]);

            BuildOneFace(meshFilter, meshData);
            yield return null;
        }
    }

    public static Vector3 PointOnCubeToPointOnSphere(Vector3 p)
    {
        return p / Mathf.Sqrt(p.x * p.x + p.y * p.y + p.z * p.z);
    }

    private MeshData CreateFace(Vector3 normal, int resolution)
    {
        Vector3 axisA = new Vector3(normal.y, normal.z, normal.x);
        Vector3 axisB = Vector3.Cross(normal, axisA);

        Vector3[] vertices = new Vector3[resolution * resolution];
        int[] triangles = new int[(resolution - 1) * (resolution - 1) * 6];
        int triIndex = 0;

        for (int y = 0; y < resolution; y++)
        {
            for (int x = 0; x < resolution; x++)
            {
                int vertexIndex = x + y * resolution;
                Vector2 t = new Vector2(x, y) / (resolution - 1f);
                Vector3 point = normal + axisA * (2 * t.x - 1) + axisB * (2 * t.y - 1);
                vertices[vertexIndex] = point;

                if (x != resolution - 1 && y != resolution - 1)
                {
                    triangles[triIndex + 0] = 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;
                }
            }
        }

        return new MeshData(vertices, triangles);
    }

    private MeshData[] GenerateFaces(int resolution)
    {
        MeshData[] allMeshDatas = new MeshData[6];
        Vector3[] faceNormals =
        {
            Vector3.up,
            Vector3.down,
            Vector3.left,
            Vector3.right,
            Vector3.forward,
            Vector3.back,
        };

        for (int i = 0; i < faceNormals.Length; i++)
        {
            allMeshDatas[i] = CreateFace(faceNormals[i], resolution);
        }

        return allMeshDatas;
    }

    public class MeshData
    {
        public Vector3[] vertices;
        public int[] triangles;

        public MeshData(Vector3[] vertices, int[] triangles)
        {
            this.triangles = triangles;
            this.vertices = vertices;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值