unity三维地球模型生成

准备一张贴图
 
创建材质球
 
球面坐标系转直角坐标系
x=rsinθcosφ.
y=rsinθsinφ.
z=rcosθ.
效果如下
 
脚本如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//创建球形mesh
public class BallCreater : MonoBehaviour {
    public Material ballMat;//材质
	void Start () {
        createBall("mEarth",new Vector3(0,0,0),100.0f,181,88);
    }

    void Update () {
		
	}
    /// <summary>
    /// 创建球形mesh
    /// </summary>
    /// <param name="meshName">名称</param>
    /// <param name="center">球心</param>
    /// <param name="radius">半径</param>
    /// <param name="longPart">经线数</param>
    /// <param name="latPart">纬线数</param>
    /// <returns></returns>
    private GameObject createBall(string meshName,Vector3 center, float radius, int longPart, int latPart)
    {
        GameObject meshObject = new GameObject(meshName);

        int verticeNum = longPart * latPart+2* longPart;//经线数*纬线数+极点处多个重合点 (首尾经线重合)
        Vector3[] vertices = new Vector3[verticeNum];//顶点数组 
        Vector3[] normals = new Vector3[verticeNum];//顶点法线数组
        Vector2[] uvs = new Vector2[verticeNum];//uv数组
        int[] triangles = new int[(longPart-1)* latPart * 3 * 2];//三角集合数组,保存顶点索引 

        float degreesToRadians = Mathf.PI / 180.0f; //弧度转换
        float deltaLong = 360.0f /(longPart-1);//经度每份对应度数
        float deltaLat = 180.0f/ (latPart+2);//纬度每份对应度数
        //极点放置多个顶点,同位置不同uv
        for (int i = 0; i < longPart; i++)
        {
            vertices[i] = new Vector3(0, 0, 1) * radius;
            normals[i] = vertices[0].normalized;
            uvs[i] = new Vector2((float)i/(float)longPart,0);
        } 
        int k = 0; 
        for (int i = 0; i < longPart-1; i++)
        {
            triangles[k++] = i; 
            triangles[k++] = i+ longPart;
            triangles[k++] = i + longPart+1;
        }  
        for (int tempLat = 0; tempLat < latPart; tempLat++) 
        { 
            float tempAngle1 = ((tempLat+1)* deltaLat) * degreesToRadians; 
            for (int tempLong = 0; tempLong < longPart; tempLong++) 
            {
                float tempAngle2 = (tempLong*deltaLong) * degreesToRadians; 
                int tempIndex = tempLong+ tempLat* longPart+ longPart; 
                vertices[tempIndex] = new Vector3(Mathf.Sin(tempAngle1) * Mathf.Cos(tempAngle2), Mathf.Sin(tempAngle1) * Mathf.Sin(tempAngle2), Mathf.Cos(tempAngle1)) * radius;
                normals[tempIndex] = vertices[tempIndex].normalized;
                uvs[tempIndex] = new Vector2((float)tempLong / (float)longPart, (float)tempLat / (float)latPart);
                if (tempLat!= latPart-1)
                {
                    if (tempLong != longPart-1)
                    {
                        triangles[k++] = tempLong + tempLat * longPart + longPart;
                        triangles[k++] = tempLong + tempLat * longPart + 2 * longPart;
                        triangles[k++] = tempLong + tempLat * longPart + longPart + 1;

                        triangles[k++] = tempLong + tempLat * longPart + 2 * longPart;
                        triangles[k++] = tempLong + tempLat * longPart + 1 + 2 * longPart;
                        triangles[k++] = tempLong + tempLat * longPart + 1 + longPart;

                    } 
                }  
            } 
        }
        //极点放置多个顶点,同位置不同uv
        for (int i = 0; i < longPart; i++)
        {
            vertices[verticeNum - 1-i] = new Vector3(0, 0, -1) * radius;
            normals[verticeNum - 1-i] = vertices[verticeNum - 1].normalized;
            uvs[verticeNum - 1-i] = new Vector2(1.0f-(float)i / (float)longPart, 1.0f); 
        } 
        for (int i = 0; i < longPart-1; i++)
        {
            triangles[k++] = verticeNum - 1-i; 
            triangles[k++] = verticeNum - 1-i- longPart;
            triangles[k++] = verticeNum - 2 - i- longPart;
        } 

        Mesh mesh = new Mesh();
        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.normals = normals;
        mesh.uv = uvs;
        mesh.RecalculateBounds();
        mesh.RecalculateNormals();
        meshObject.AddComponent<MeshFilter>();
        meshObject.AddComponent<MeshRenderer>();
        meshObject.GetComponent<MeshFilter>().mesh = mesh;
        meshObject.GetComponent<MeshRenderer>().material = ballMat;
        meshObject.transform.position += center;
        return meshObject;
    }

}

 

posted @ 2018-12-14 21:57  星河太守  阅读(6338)  评论(0编辑  收藏  举报