Recently have been engaged in flash3d, as if a little sorry unity3d friends. This time, simply write a script that dynamically creates a terrain grid to share with you.
This is the first part, which only achieves the dynamic generation of terrain through a height map. If in the future have mood and time, then come slowly to add multi-channel brush terrain material, dynamic brush terrain and save height map function bar. I did not like the public script source, are part of a separate explanation and then let friends themselves to combine, but the recent time is not much, so or directly provide the source code, and then write the comments on the source, we see it by ourselves. The source code is at the bottom. First drag the script directly onto an object, run, there will appear a patch shown. This is because I called the following Setterrain method in start for the convenience of testing. This method creates a default terrain panel. The length width is 100*100, the segment number is 50*50, the height is 10 meters to 10 meters. Of course, when we really use it, we use the overloaded Setterrain method to make the values of the length and width heights and the number of segments, and comment out the methods in start.
Now that I have not specified the default ground material and height map, I have written a warning hint. These two variables are material and height map, we can find a way to assign value. I am now writing public just to facilitate the assignment test, preferably write the Get/set method assignment. Also, there is no multi-channel material for the ground, so it just uses a default shader. If you need to mix channel material later, change this shader. OK, regardless of the future, a material ball with a grass texture is paid to the script.
Out of a meadow
I brushed a height map in black and white, then threw it into the script. Note that, as a picture of a height map, you need to set read and write permissions, otherwise you will not get the color of the pixel
There was a small hillside.
In fact, I do not have this script for black and white pictures, I casually took a wooden box map, the same can do the height map, this is because I do grayscale processing, and finally get the image pixel point of gray value.
Look, the terrain is coming out. Actual effect function is simple point, here provides a little bit of thinking, there is a need or interested friends can refer to the practice, the expansion of their own. Source: terrainmanager.cs using unityengine;using system.collections; public class TerrainManager: Monobehaviour { //material and height map Public Material diffusemap; public texture2d HEIGHTMAP;&N Bsp //vertices, Uvs, index information private vector3[] vertives; private vector2[] uvs; Private int[ ] triangles; //Generate information Private Vector2 size;//length/width private float minheight = -10;& nbsp Private float maxheight = 10; Private Vector2 segment; private float unith; //patch mesh &N Bsp Private Gameobject terrain; //Use this for initializationvoid Start () { //default generate a terrain if not like , log off and then generate with parameters setterrain ();} //<summary> //Generate default terrain //</summary> public void Setterrain () { Setterrain (10 0, +, 50,-10,10); } //<summary> //create terrain via parameters /// lt;/summary> //<param name= "width" > Terrain width </param> //<param name= "height" > Terrain Length </param> //<param name= "Segmentx" > Width number of segments </param> //<param Name= "Segmenty" > Length of Segment </param> //<param name= "min" > Minimum height </param> // <param name= "Max" > Maximum height </param> public void Setterrain (float width, float height, uint segmentx, UINT Segmenty,int Min,int max) { Init (width, height, segmentx, Segmenty,min,max), & nbsp getvertives (); DrawMesh (); } //<summa ry> ///initialization calculates some values &NBSp //</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, I NT Max) { size = new Vector2 (width, height); MaxHeight = max; MinHeight = min; Unith = maxheight-minheight; segment = new Vector2 (Segmentx, Segmenty); if (terrain! = null) &NBS P { Destroy (terrain); } &NBSP ; Terrain = new Gameobject (); terrain.name = "plane"; } //<summary> // /Draw grid //</summary> private void DrawMesh () { Me SH mesh = terrain. Addcomponent<meshfilter> () .mesh; terrain. Addcomponent<meshrenderer> (); if (Diffusemap = = null) { debug.logwarning ("No material,create diffuse!!"); Diffusemap = new Material (Shader.find ("diffuse")); }& nbsp if (heightmap==null) { DEBUG.LOGW Arning ("No heightmap!!!"); } terrain.renderer.material = diffusemap; &NBSP ; Assign a value to mesh mesh. Clear (); mesh.vertices = vertives;//,pos); MESH.UV = uvs; &NBSP ; Mesh.triangles = triangles; //Reset normal mesh. Recalculatenormals (); //Reset range mesh. Recalculatebounds (); } //<summary> //Generate vertex information //</ summary> ///<returns></returns> private vector3[] getvertives () { int sum = Mathf.floortoint ((segment.x + 1) * (Segment.y + 1)); Flo At w = size.x/segment.x; float h = size.y/segment.y; int i Ndex = 0; GETUV (); gettriangles (); Vertiv es = new vector3[sum]; for (int i = 0; i < SEGMENT.Y + 1;i++) { for (int j = 0; J < Segment.x + 1; + j)   ; { float tempheight = 0; &n Bsp if (heightmap! = null) {& nbsp tempheight = GetHeight (Heightmap, Uvs[index]); } Vertives[index] = new Vector3 (J * W, Tempheight, I * h); index++; &NB Sp } } return vertives; } <summary> //Generate UV Information //</summary> //<returns></retur Ns>&nBsp Private vector2[] Getuv () { int sum =mathf.floortoint ((segment.x + 1) * (s Egment.y + 1); Uvs = new vector2[sum]; float u = 1.0f/segment.x;& nbsp 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 Ve Ctor2 (J * U, I * v); index++; &NB Sp } } return uvs; } //<summary> ; //Generate index Information //</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++) { &NBSP ; for (int j = 0; J < Segment.x; J + +) { INT role = Mathf.floortoint (segment.x) + 1; I NT Self = j + (I*role); int next = J + ((i+1) * role); Triangles[index] = self; &N Bsp Triangles[index + 1] = next + 1; Triangles[index + 2] = self + 1; Triangles[index + 3] = self;  ; Triangles[index + 4] = next; &NB Sp Triangles[index + 5] = next + 1; index + 6; &N Bsp } } return triangles; } &nbs p; Private float getheight (texture2d texture, Vector2 UV) { &NBSP;&NBSP;&NBS P if (texture! = null) { //extract grayscale. If you force a channel to be read, you can ignore Color c = GetColor (texture, UV); &NBSP ; Float Gray = c.grayscale;//or can specify its own grayscale extraction algorithm, such as: Gray = 0.3F * C.R + 0.59F * C.G + 0.11F * c.b; &NB Sp float h = unith * gray; return h; }   ; else { return 0; &NB Sp } } //<summary> //Get the color of a point on the image //</summary> &NB Sp <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> //location coordinates of the terrain from outside //</SU mmary> //<param name= "POS" ></param> public void SetpoS (Vector3 Pos) { if (terrain) { &NB Sp terrain.transform.position = pos; } else { Setterrain (); terrain.tr Ansform.position = pos; } }}
Unity3d dynamic creation of terrain grids (i)