Programmatically change Unity TerrainData with C# (用C#代码来动态改变地形数据)
Unity terrain data could be changed by c# code. You could change the height data and atlas alpha texture, remove or add grass or tree at runtime dynamically.
- Change Terrain Height
public void ModifyTerrainDataHeight(TerrainData terrainData)
{
int width = terrainData.heightmapWidth;
int height = terrainData.heightmapHeight;
float[,] array = new float[width, height];
print("width:" + width + " height:" + height);
for (int i = 0; i < width; i++)
for (int j = 0; j < height; j++)
{
float f1 = i;
float f2 = width;
float f3 = j;
float f4 = height;
float baseV = (f1 / f2 + f3 / f4) / 2 * 1;
array[i, j] = baseV * baseV;
}
// restore the old heights as need
heightsBackups = terrainData.GetHeights(0, 0, width, height);
// set up new heights
terrainData.SetHeights(0, 0, array);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- Change Terrain Alphamap with a new one
void SetAtlasAlpha(TerrainData terrainData, Texture2D splatAlpha)
{
float[,,] maps = terrainData.GetAlphamaps(0, 0, terrainData.alphamapWidth, terrainData.alphamapHeight);
for (int y = 0; y < terrainData.alphamapHeight; y++)
{
for (int x = 0; x < terrainData.alphamapWidth; x++)
{
Color col = splatAlpha.GetPixel(x, y);
maps[x, y, 0] = col.r;
maps[x, y, 1] = col.g;
maps[x, y, 2] = col.b;
maps[x, y, 3] = col.a;
}
}
terrainData.SetAlphamaps(0, 0, maps);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- Clean some trees / or remove some trees on the roads
void RemoveTreesOnRoad(Terrain terrain)
{
if ( terrain.GetComponent<TerrainCollider>() != null && terrain.GetComponent<TerrainCollider>().enabled )
{
UnityEngine.Debug.LogWarning("Please disable TerrainCollider before remove ");
return;
}
TerrainData terrainData = terrain.terrainData;
Vector3 size = terrainData.size;
Debug.Log("size: " + size);
Vector3 pos = terrain.GetPosition();
TreeInstance[] treeInstances = terrainData.treeInstances;
List<TreeInstance> list = new List<TreeInstance>();
float distance = size.y;
foreach(TreeInstance ti in treeInstances)
{
Vector3 treePos = new Vector3( ti.position.x * size.x , ti.position.y * size.y, ti.position.z * size.z ) + pos;
RaycastHit hit;
if ( Physics.Raycast(treePos + Vector3.up * distance, Vector3.down, out hit, distance * 2f) )
{
// this tree spawned on the road
}
else
{
list.Add(ti);
}
}
terrainData.treeInstances = list.ToArray();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
- Clean all details or grass
int detailResolution = terrainData.detailResolution;
for (int layer = 0; layer < terrainData.detailPrototypes.Length; layer++)
{
int[,] detailLayer = terrainData.GetDetailLayer(0, 0, detailResolution, detailResolution, layer);
for (int j = 0; j < detailResolution; j++)
{
for (int k = 0; k < detailResolution; k++)
{
detailLayer[j, k] = 0;
}
}
terrainData.SetDetailLayer(0, 0, layer, detailLayer);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14

评论
发表评论