unity 通过图片信息制作地形图

来源:互联网 发布:江恩正方软件 编辑:程序博客网 时间:2024/06/05 01:57
using System.Collections;using System.Collections.Generic;using UnityEngine;public class testTerrain : MonoBehaviour {public Material diffuseMap;public Texture2D heightMap;//顶点、uv、索引信息private Vector3[] vertives;private Vector2[] uvs;private int[] triangles;//生成信息private Vector2 size;//长宽private float minHeight = -10;private float maxHeight = 10;private Vector2 segment;private float unitH;//面片meshprivate GameObject terrain;// Use this for initializationvoid Start(){//默认生成一个地形,如果不喜欢,注销掉然后用参数生成SetTerrain();}/// <summary>/// 生成默认地形/// </summary>public void SetTerrain(){SetTerrain(100, 100, 50, 50, -10, 10);}/// <summary>/// 通过参数生成地形/// </summary>/// <param name="width">地形宽度</param>/// <param name="height">地形长度</param>/// <param name="segmentX">宽度的段数</param>/// <param name="segmentY">长度的段数</param>/// <param name="min">最低高度</param>/// <param name="max">最高高度</param>public void SetTerrain(float width, float height, uint segmentX, uint segmentY, int min, int max){Init(width, height, segmentX, segmentY, min, max);GetVertives();DrawMesh();}/// <summary>/// 初始化计算某些值/// </summary>/// <param name="width"></param>/// <param name="height"></param>/// <param name="segmentX"></param>/// <param name="segmentY"></param>/// <param name="min"></param>/// <param name="max"></param>private void Init(float width, float height, uint segmentX, uint segmentY, int min, int max){size = new Vector2(width, height);maxHeight = max;minHeight = min;unitH = maxHeight - minHeight;segment = new Vector2(segmentX, segmentY);if (terrain != null){Destroy(terrain);}terrain = new GameObject();terrain.name = "plane";}/// <summary>/// 绘制网格/// </summary>private void DrawMesh(){Mesh mesh = terrain.AddComponent<MeshFilter>().mesh;terrain.AddComponent<MeshRenderer>();if (diffuseMap == null){Debug.LogWarning("No material,Create diffuse!!");diffuseMap = new Material(Shader.Find("Diffuse"));}if (heightMap == null){Debug.LogWarning("No heightMap!!!");}//terrain.renderer.material = diffuseMap;//给mesh 赋值mesh.Clear();mesh.vertices = vertives;//,pos);mesh.uv = uvs;mesh.triangles = triangles;//重置法线mesh.RecalculateNormals();//重置范围mesh.RecalculateBounds();}/// <summary>/// 生成顶点信息/// </summary>/// <returns></returns>private Vector3[] GetVertives(){int sum = Mathf.FloorToInt((segment.x + 1) * (segment.y + 1));float w = size.x / segment.x;float h = size.y / segment.y;int index = 0;GetUV();GetTriangles();vertives = new Vector3[sum];for (int i = 0; i < segment.y + 1; i++){for (int j = 0; j < segment.x + 1; j++){float tempHeight = 0;if (heightMap != null){tempHeight = GetHeight(heightMap, uvs[index]);}vertives[index] = new Vector3(j * w, tempHeight, i * h);index++;}}return vertives;}/// <summary>/// 生成UV信息/// </summary>/// <returns></returns>private Vector2[] GetUV(){int sum = Mathf.FloorToInt((segment.x + 1) * (segment.y + 1));uvs = new Vector2[sum];float u = 1.0F / segment.x;float v = 1.0F / segment.y;uint index = 0;for (int i = 0; i < segment.y + 1; i++){for (int j = 0; j < segment.x + 1; j++){uvs[index] = new Vector2(j * u, i * v);index++;}}return uvs;}/// <summary>/// 生成索引信息/// </summary>/// <returns></returns>private int[] GetTriangles(){int sum = Mathf.FloorToInt(segment.x * segment.y * 6);triangles = new int[sum];uint index = 0;for (int i = 0; i < segment.y; i++){for (int j = 0; j < segment.x; j++){int role = Mathf.FloorToInt(segment.x) + 1;int self = j + (i * role);int next = j + ((i + 1) * role);triangles[index] = self;triangles[index + 1] = next + 1;triangles[index + 2] = self + 1;triangles[index + 3] = self;triangles[index + 4] = next;triangles[index + 5] = next + 1;index += 6;}}return triangles;}private float GetHeight(Texture2D texture, Vector2 uv){if (texture != null){//提取灰度。如果强制读取某个通道,可以忽略Color c = GetColor(texture, uv);float gray = c.grayscale;//或者可以自己指定灰度提取算法,比如:gray = 0.3F * c.r + 0.59F * c.g + 0.11F * c.b;float h = unitH * gray;return h;}else{return 0;}}/// <summary>/// 获取图片上某个点的颜色/// </summary>/// <param name="texture"></param>/// <param name="uv"></param>/// <returns></returns>private Color GetColor(Texture2D texture, Vector2 uv){Color color = texture.GetPixel(Mathf.FloorToInt(texture.width * uv.x), Mathf.FloorToInt(texture.height * uv.y));return color;}/// <summary>/// 从外部设置地形的位置坐标/// </summary>/// <param name="pos"></param>public void SetPos(Vector3 pos){if (terrain){terrain.transform.position = pos;}else{SetTerrain();terrain.transform.position = pos;}}}