using System.Collections; using System.Collections.Generic; using UnityEngine; [ExecuteInEditMode] [RequireComponent(typeof(MeshRenderer))] [RequireComponent(typeof(MeshFilter))] class TerrainScript : MonoBehaviour { int m_SegmentCount_x; int m_SegmentCount_z; float m_Size = 0.01f; MeshFilter filter; Transform controllerTarget; Texture2D m_HeightMap; void Start() { filter = GetComponent(); controllerTarget = GameObject.Find("ControllerTarget").transform; m_HeightMap = Resources.Load("mars_height") as Texture2D; } public float GetY(float x, float z, float heightScale) { Color mapColour = m_HeightMap.GetPixelBilinear(x, z); return sinh((mapColour.grayscale-0.5f)*heightScale); } private float sinh(float x) { return ((1 - Mathf.Exp(-2*x))/(2*(Mathf.Exp(-x)))); } void Update() { m_SegmentCount_x = Mathf.FloorToInt(controllerTarget.position.x / m_Size); m_SegmentCount_z = Mathf.FloorToInt(controllerTarget.position.z / m_Size); MeshBuilder meshBuilder = new MeshBuilder(); float heightScale = ((controllerTarget.rotation.eulerAngles.y)/360.0f)*0.1f; for (int i = 0; i <= m_SegmentCount_z; i++) { float z = m_Size * i; float v = (1.0f / m_SegmentCount_z) * i; for (int j = 0; j <= m_SegmentCount_x; j++) { float x = m_Size * j; float u = (1.0f / m_SegmentCount_x) * j; Vector3 offset = new Vector3(x, GetY(x,z, heightScale), z); Vector2 uv = new Vector2(u, v); bool buildTriangles = i > 0 && j > 0; BuildQuadForGrid(meshBuilder, offset, uv, buildTriangles, m_SegmentCount_x + 1); } } filter.sharedMesh = meshBuilder.CreateMesh(); } void BuildQuadForGrid(MeshBuilder meshBuilder, Vector3 position, Vector2 uv, bool buildTriangles, int vertsPerRow) { meshBuilder.Vertices.Add(position); meshBuilder.UVs.Add(uv); if (buildTriangles) { int baseIndex = meshBuilder.Vertices.Count - 1; int index0 = baseIndex; int index1 = baseIndex - 1; int index2 = baseIndex - vertsPerRow; int index3 = baseIndex - vertsPerRow - 1; meshBuilder.AddTriangle(index0, index2, index1); meshBuilder.AddTriangle(index2, index3, index1); } } } public class MeshBuilder { private List m_Vertices = new List(); public List Vertices { get { return m_Vertices; } } private List m_Normals = new List(); public List Normals { get { return m_Normals; } } private List m_UVs = new List(); public List UVs { get { return m_UVs; } } private List m_Indices = new List(); public void AddTriangle(int index0, int index1, int index2) { m_Indices.Add(index0); m_Indices.Add(index1); m_Indices.Add(index2); } public Mesh CreateMesh() { Mesh mesh = new Mesh(); mesh.vertices = m_Vertices.ToArray(); mesh.triangles = m_Indices.ToArray(); //Normals are optional. Only use them if we have the correct amount: if (m_Normals.Count == m_Vertices.Count) mesh.normals = m_Normals.ToArray(); mesh.uv = m_UVs.ToArray(); mesh.RecalculateBounds(); return mesh; } }