unity3d 地形概述

前言:
本文不是讲地形编辑器的使用,而是主要讲解(1)地形相关知识(2)使用代码创建地形(3)使用AnimationCurve创建曲面地形(4)使用photoshop绘制地形表面,即SplatAlphaMap(5)使用代码为地形添加树

                         地形

本讲结构:
一:地形的基础知识
(1)地形编辑器的不足
(2)地形结构
(3)地形与SplatAlpha
二:动态创建地形
(1)动态创建简单平面地形
(2)动态创建凹凸地形
(3)利用AnimationCurve创建特殊曲线地形。
(4)动态创建地形,并设置splatPrototypes,最后使用photoShop绘制2D图编辑地形贴图。
(5)动态创建地形,使用photoShop绘制 多张splats
三:地形与树
(1)TreePrototypes
(2)TreeInstances


一:地形的基础知识
(0)基本术语
Splat:地形所使用的贴图,即Terrain Texture。术语叫Splat或者 Splat map。
Splat Alhpa Map:地形贴图布局图,用图的rgba各个通道来表示贴图在地形上的使用,project界面里展开地形即可看见。术语叫Splat Alpha Map,或者Alpha Map.

(1)地形编辑器的不足
地形Terrain是3D游戏里必不可少的一部分。Unity提供的地形编辑器也十分好用,但是依然有少许不足和缺陷。
Unity地形编辑器的不足:
1)地形只能是成片的抬高或者降低。如果想定制某特定斜率,或者特定曲线的地形就没法实现了。
2)地形不能实时改变。
不过Unity提供了强大的地形脚本接口,可以弥补上述不足。

(2)地形结构
首先要清楚, Terrain地形的包括Heightmap高度图,贴图信息,树信息等几乎所有数据都是储存TerrainData里,而TerrainData可以保存成地形文件,地形文件后缀为.asset。任意工程导入地形文件后,在project窗口下都会显示为地形文件。
TerrainData的基本属性:
1.terrainData.heightmapResolution int,高度图的长宽分辨率,一般是2的幂加1, 如513

2.terrainData.baseMapResolution int,Resolution of the base map used for rendering far patches on the terrain

如513

3.terrainData.size:   Vector3,地形世界里的尺寸,world unit. 如new Vector3(50, 50, 50);

4.terrainData.alphamapResolution alphamap的分辨率,如512;


地形贴图信息储存在Terrain之下的SplatAlpha图里。在project窗口展开一个地形,会看到之下的贴图信息,名称格式为SplatAlpha xx.
【风宇冲】Unity3D教程宝典之地形

(3)地形与SplatAlpha
在SplatAlpha图中
红=第1张贴图
绿=第2张贴图
蓝=第3张贴图
Alpha=第4张贴图
第5张贴图开始,会创建新的SplatAlpha图,然后继续 红绿蓝黑 如此循环。

alphamap:指的是纹理中某通道的颜色,   refer to a grayscale image residing in a single channel of a texture
Splat:一张纹理贴图和其对应的alphamap统称为一个splat。 主要是分块,divide in chunks.所以可以使用LOD等技术

terrainData.splatPrototypes 就是地形包含的贴图信息

splatPrototypes 为SplatPrototype[],

SplatPrototype为单张贴图信息

SplatPrototype的属性有

SplatPrototype.texture     Texture2D,地形贴图

SplatPrototype.tileOffset   Vector2,图块偏移

SplatPrototype.tileSize     Vector2,图块尺寸(World Unit)

terrainData.SetAlphamaps(int x,int y,float[,,]) ,其中x,y为起点

float[i,j,k]为通道信息,i,j为对应的点,k为第几张图,float值储存的是该点该图的灰度值。

terrainData.splatPrototypes的长度 = 贴图数量 = splatArray (float[,,])的第三维的长度


二:动态创建地形
(1)动态创建 简单平面地形
创建地形是不需要using  UnityEditor的,这里使用了AssetDatabase,所以需using  UnityEditor;
创建三步:
1.TerrainData   terrainData =  new TerrainData();
2.设置terrainData的属性
3.根据terrainData创建地形

  GameObject obj = Terrain.CreateTerrainGameObject(terrainData);

具体脚本如下:
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEditor;

  4. public class Tutor_1_CreateSimpleTerrain : MonoBehaviour {
  5. void Start()
  6. {
  7. CreateTerrain();
  8. }
  9. public Terrain CreateTerrain()
  10. {
  11. TerrainData  terrainData = new TerrainData();
  12. terrainData.heightmapResolution = 513;
  13. terrainData.baseMapResolution = 513;
  14. terrainData.size = new Vector3(50, 50, 50);
  15. terrainData.alphamapResolution = 512;
  16.      terrainData.SetDetailResolution(32, 8);
  17. GameObject obj = Terrain.CreateTerrainGameObject(terrainData);
  18. AssetDatabase.CreateAsset(terrainData, "Assets/Tutorial/Tutor_1_SimpleTerrain.asset");
  19.      AssetDatabase.SaveAssets();
  20. return  obj.GetComponent<</span>Terrain>();
  21. }
  22. }

(2)动态创建凹凸地形
接下来改变地形的高度。地形高度是用heightmap存储的。
代码里通过TerrainData.GetHeights()读取高度图里的二维高度数组,
通过TerrainData.SetHeights()设置高度图里的二维高度数组。
TerrainData.GetHeights(int x的起点,int y的起点,int 读取高度的宽度范围, int  读取高度的高度范围 ),返回float[,] ,二维高度数组
TerrainData.SetHeights(int x的起点,int y的起点,float[,]  二维高度数组 ),返回void

例子:在创建地形前,改变地形的高度,代码如下:
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEditor;

  4. public class Tutor_2_CreateTerrain_ModifyHeight : MonoBehaviour {
  5. void Start()
  6. {
  7. CreateTerrain();
  8. }
  9. public Terrain CreateTerrain()
  10. {
  11. TerrainData  terrainData = new TerrainData();
  12. terrainData.heightmapResolution = 513;
  13. terrainData.baseMapResolution = 513;
  14. terrainData.size = new Vector3(50, 50, 50);
  15. terrainData.alphamapResolution = 512;
  16.      terrainData.SetDetailResolution(32, 8);
  17. ModifyTerrainDataHeight(terrainData);
  18. GameObject obj = Terrain.CreateTerrainGameObject(terrainData);
  19. AssetDatabase.CreateAsset(terrainData,"Assets/Tutorial/Tutor_2_Terrain_ModifyHeight.asset");
  20.      AssetDatabase.SaveAssets();
  21. return  obj.GetComponent<</span>Terrain>();
  22. }
  23. public void ModifyTerrainDataHeight(TerrainData terrainData)
  24. {
  25. int width = terrainData.heightmapWidth;
  26. int height = terrainData.heightmapHeight;
  27. float[,] array = new float[width,height];
  28. print ("width:"+ width +" height:"+ height );
  29. for(int i=0; i< width;i++)
  30. for(int j=0; j< height;j++)
  31. {
  32. float f1 = i;
  33. float f2 = width;
  34. float f3 = j;
  35. float f4 = height;
  36. float baseV =  (f1/f2 + f3/f4)/2 *  1;
  37. array[i,j] =baseV*baseV;
  38. }
  39. terrainData.SetHeights(0,0,array);
  40. }
  41. }

 

(3)利用AnimationCurve创建特殊曲线地形。
之前风宇冲有一篇关于AnimationCurve的教程,现在我们就来看看如何用AnimationCurve来控制地形的起伏。
步骤:
1.创建一个新场景,并新建一个GameObject起名为Manager,新建一个名为Tutor_3_CreateTerrainWithAnimati onCurve.cs的脚本并拖至Manager上。
2.粘贴并覆盖如下脚本至Tutor_3_CreateTerrainWithAnimati onCurve里
 
  1. using UnityEngine;
  2. using System.Collections;

  3. public class Tutor_3_CreateTerrainWithAnimationCurve : MonoBehaviour {
  4. public AnimationCurve animationCurve;
  5. }
3.在Manager的Inspector面板里双击Animation Curve。在弹出曲线绘制界面后,绘制任意曲线,如下。
【风宇冲】Unity3D教程宝典之地形

之后还是设置高度,即terrainData.SetHeights(0,0,array);只是对array里高度的赋值变为如下

array[i,j] = animationCurve.Evaluate(f1/f2); 其中f1是array里的y,f2是整个高度图的高度。具体代码如下:

  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEditor;

  4. public class Tutor_3_CreateTerrainWithAnimationCurve : MonoBehaviour {
  5. public AnimationCurve animationCurve;
  6. void Start()
  7. {
  8. CreateTerrain();
  9. }
  10. public Terrain CreateTerrain()
  11. {
  12. TerrainData  terrainData = new TerrainData();
  13. terrainData.heightmapResolution = 513;
  14. terrainData.baseMapResolution = 513;
  15. terrainData.size = new Vector3(50, 50, 50);
  16. terrainData.alphamapResolution = 512;
  17.      terrainData.SetDetailResolution(32, 8);
  18. ModifyTerrainDataHeight(terrainData);
  19. GameObject obj = Terrain.CreateTerrainGameObject(terrainData);
  20. AssetDatabase.CreateAsset(terrainData,"Assets/Tutorial/Tutor_3_TerrainWithAnimationCurve.asset");
  21.      AssetDatabase.SaveAssets();
  22. return  obj.GetComponent();
  23. }
  24. public void ModifyTerrainDataHeight(TerrainData terrainData)
  25. {
  26. int width = terrainData.heightmapWidth;
  27. int height = terrainData.heightmapHeight;
  28. float[,] array = new float[width,height];
  29. print ("width:"+ width +" height:"+ height );
  30. for(int i=0; i< width;i++)
  31. for(int j=0; j< height;j++)
  32. {
  33. float f1 = j;
  34. float f2 = height;
  35. array[i,j] = animationCurve.Evaluate(f1/f2);
  36. }
  37. terrainData.SetHeights(0,0,array);
  38. }
  39. }

最后创建的地形和我们之前设置的曲线一致。

【风宇冲】Unity3D教程宝典之地形


(4)动态创建地形,并设置splatPrototypes,最后使用photoShop绘制2D图编辑地形贴图。
步骤:
1.创建一个新场景并命名为Tutor_4_CreateTerrainWithSplat,并新建一个GameObject起名为Manager,新建一个名为
Tutor_4_CreateTerrainWithSplat.cs的脚本并拖至Manager上。
2.粘贴并覆盖如下脚本至Tutor_4_CreateTerrainWithSplat里,该脚本与上个例子的脚本基本一致。
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEditor;

  4. public class Tutor_4_CreateTerrainWithSplat : MonoBehaviour {
  5. public AnimationCurve animationCurve;
  6. void Start()
  7. {
  8. CreateTerrain();
  9. }
  10. public Terrain CreateTerrain()
  11. {
  12. TerrainData  terrainData = new TerrainData();
  13. terrainData.heightmapResolution = 513;
  14. terrainData.baseMapResolution = 513;
  15. terrainData.size = new Vector3(50, 50, 50);
  16. terrainData.alphamapResolution = 512;
  17.      terrainData.SetDetailResolution(32, 8);
  18. ModifyTerrainDataHeight(terrainData);
  19. GameObject obj = Terrain.CreateTerrainGameObject(terrainData);
  20. AssetDatabase.CreateAsset(terrainData, "Assets/Tutorial/Tutor_4_TerrainWithSplats.asset");
  21.      AssetDatabase.SaveAssets();
  22. return  obj.GetComponent<</span>Terrain>();
  23. }
  24. public void ModifyTerrainDataHeight(TerrainData terrainData)
  25. {
  26. int width = terrainData.heightmapWidth;
  27. int height = terrainData.heightmapHeight;
  28. float[,] array = new float[width,height];
  29. print ("width:"+ width +" height:"+ height );
  30. for(int i=0; i< width;i++)
  31. for(int j=0; j< height;j++)
  32. {
  33. float f1 = j;
  34. float f2 = height;
  35. array[i,j] = animationCurve.Evaluate(f1/f2);
  36. }
  37. terrainData.SetHeights(0,0,array);
  38. }
  39. }
之后添加地形贴图变量,在脚本里加上public  Texture2D[] splats;
然后在Inspector里指定任意一张贴图。
现在开始添加Splat了。
核心是SplatPrototype,也就是Splat原型的信息,包含贴图信息和地形块的信息。
SplatPrototype  outSplatPrototype =  new SplatPrototype();
之后设置SplatPrototype的如下属性

outSplatPrototype.texture: 贴图

outSplatPrototype.tileOffset:地形块的偏移。

outSplatPrototype.tileSize:地形块的尺寸

组成好SplatPrototype[] outSplatPrototypes后,赋予TerrainData.splatPrototypes 即可。

代码如下。
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEditor;

  4. public class Tutor_4_CreateTerrainWithSplat : MonoBehaviour {
  5. public AnimationCurve animationCurve;
  6. public Texture2D[] splats;
  7. void Start()
  8. {
  9. CreateTerrain();
  10. }
  11. public Terrain CreateTerrain()
  12. {
  13. TerrainData  terrainData = new TerrainData();
  14. terrainData.heightmapResolution = 513;
  15. terrainData.baseMapResolution = 513;
  16. terrainData.size = new Vector3(50, 50, 50);
  17. terrainData.alphamapResolution = 512;
  18.      terrainData.SetDetailResolution(32, 8);
  19. terrainData.splatPrototypes = CreateSplatPrototypes(splats,new Vector2(15,15),newVector2(0,0)); 
  20. ModifyTerrainDataHeight(terrainData);
  21. GameObject obj = Terrain.CreateTerrainGameObject(terrainData);
  22. AssetDatabase.CreateAsset(terrainData, "Assets/Tutorial/Tutor_4_TerrainWithSplats.asset");
  23.      AssetDatabase.SaveAssets();
  24. return  obj.GetComponent<</span>Terrain>();
  25. }
  26. public void ModifyTerrainDataHeight(TerrainData terrainData)
  27. {
  28. int width = terrainData.heightmapWidth;
  29. int height = terrainData.heightmapHeight;
  30. float[,] array = new float[width,height];
  31. for(int i=0; i< width;i++)
  32. for(int j=0; j< height;j++)
  33. {
  34. float f1 = j;
  35. float f2 = height;
  36. array[i,j] = animationCurve.Evaluate(f1/f2);
  37. }
  38. terrainData.SetHeights(0,0,array);
  39. }
  40. public SplatPrototype[] CreateSplatPrototypes(Texture2D[] tmpTextures,Vector2 tmpTileSize,Vector2 tmpOffset)
  41. {
  42. SplatPrototype[] outSplatPrototypes = new SplatPrototype[tmpTextures.Length];
  43. for(int i =0;i
  44. {
  45. outSplatPrototypes[i] = CreateSplatPrototype(tmpTextures[i],tmpTileSize,tmpOffset);
  46. }
  47. return outSplatPrototypes;
  48. }
  49. public SplatPrototype CreateSplatPrototype(Texture2D tmpTexture, Vector2 tmpTileSize,Vector2 tmpOffset)
  50. {
  51. SplatPrototype outSplatPrototype = new SplatPrototype();
  52. outSplatPrototype.texture = tmpTexture;
  53. outSplatPrototype.tileOffset = tmpOffset;
  54. outSplatPrototype.tileSize = tmpTileSize ;
  55. return outSplatPrototype;
  56. }
  57. }
之前的例子,创建出来的地形在project界面里一直不能展开,因为没有任何splat信息。而本例中,指定TerrainData.splatPrototypes,即有了splat的原型信息后,就会自动生成splat图,因此地形可以展开了。
展开出来的SplatAlpha 01为纯红,表示整个地图铺的都是第一张地形贴图。
【风宇冲】Unity3D教程宝典之地形

现在我们再进一步,通过Photoshop绘制splat的alpha图。

1.选中Manager,在Inspector面板里,将Terrain Textures设置为任意两张贴图,这里用的是unity Terrain包里的“Grass&Rock”和 “Grass (Hill)” 两张贴图。

2.然后脚本里也添加splats属性,public Texture2D[] splatAlphaMaps;

3.打开photoshop,创建一张512x512的rgb图,先铺满红色,在绘制一些绿色,如下图

【风宇冲】Unity3D教程宝典之地形
之后导出为splatAlphaMap1.png

4.将该图拖进unity,并设置Import Settings里的 Texture Type为Advanced,然后勾选Read/Write Enable。最后把importType设置为Default(importType不能为其他的)。

【风宇冲】Unity3D教程宝典之地形

5. Manager的Inspector面板里,splatAlphaMaps,此Texture2D数组设置为1,并指定为splatAlphaMap1

6.在Tutor_4_CreateTerrainWithSplat脚本里补充以下函数

  1. public float[,,] CreateSplatAlphaArray(Texture2D[] splatAlphaMaps,int numOfSplatPrototypes )
  2. {
  3. List cArray = new List();
  4. int splatAlphaMap_SizeX = splatAlphaMaps[0].width;
  5. int splatAlphaMap_SizeY = splatAlphaMaps[0].height;
  6. float[,,] outSplatAlphaArray = new float[splatAlphaMap_SizeX,splatAlphaMap_SizeY,numOfSplatPrototypes];
  7. //第几张SplatAlphaMap
  8. for(int splatAlphaMapIndex=0; splatAlphaMapIndex
  9. {
  10. //RGBA第几个通道
  11. for(int alphaIndex =0;alphaIndex<4; alphaIndex ++)
  12. {
  13. //Splat ID
  14. int splatIndex = alphaIndex+splatAlphaMapIndex*4;
  15. //仅当Splat ID小于Splat的数量时
  16. if(splatIndex < numOfSplatPrototypes)
  17. {
  18. for (int index_heightmapY = 0; index_heightmapY < splatAlphaMap_SizeY; index_heightmapY++)
  19.        {
  20.           for (int index_heightmapX = 0; index_heightmapX < splatAlphaMap_SizeX; index_heightmapX++)
  21.            {
  22. //取第splatAlphaMapIndex张SplatAlphaMap上的位于index_heightmapY,index_heightmapX的颜色值
  23. Color c =  splatAlphaMaps[splatAlphaMapIndex].GetPixel(index_heightmapY,index_heightmapX);
  24. cArray.Add(c);
  25. //赋予outSplatAlphaArray的index_heightmapX,index_heightmapY,splatIndex对应的通道值
  26. outSplatAlphaArray[index_heightmapX, index_heightmapY, splatIndex] = c[ alphaIndex ];
  27. }
  28. }
  29. }
  30. else
  31. {
  32. return outSplatAlphaArray;
  33. }
  34. }
  35. }
  36. return outSplatAlphaArray;
  37. }

 之后在Start函数里的CreateTerrain();后面补充代码如下

  1.  void Start()
  2. {
  3. CreateTerrain();
  4. TerrainData terData =AssetDatabase.LoadAssetAtPath("Assets/Tutorial/Tutor_4_TerrainWithSplats.asset",typeof(TerrainData)) as TerrainData;
  5. float[,,] splatAlphaArray = CreateSplatAlphaArray(splatAlphaMaps, terData.splatPrototypes.Length);
  6. terData.SetAlphamaps(0,0,splatAlphaArray);
  7. }

之后点击运行,发现地形确实是我们之前在photoshop里绘制的形状,如下

【风宇冲】Unity3D教程宝典之地形

注意:
1.SetAlphamaps函数 必须在创建TerrainData文件,即xxx.asset后,再读取该TerrainData调用。

(5)动态创建地形,使用photoShop绘制 多张splats
三张以下的地形贴图一般不会出错,但是超过四张时就要注意了。用photoShop绘制a通道并导入unity是比较容易出错的。
1.打开Photoshop,新建一张图,如下。
【风宇冲】Unity3D教程宝典之地形
2.用黑色平铺整张图后,添加一个通道
【风宇冲】Unity3D教程宝典之地形
3.选中Red通道,然后用纯白画笔在顶端画一条横线
【风宇冲】Unity3D教程宝典之地形
4.用3.的方法在gba通道依次往下画横线.
【风宇冲】Unity3D教程宝典之地形  【风宇冲】Unity3D教程宝典之地形
5.保存成splatAlpha.psd文件并拖入unity工程。
注意:如果导入的贴图是有a通道的话,一定要保证在Preview里看到的是RGBA,即有A的字样。有时候在photoshop里即使有a,保存成png或者tga再导入unity,有时候会没有A,那么就是错的。
【风宇冲】Unity3D教程宝典之地形

6.打开(4)里创建的Tutor_4_CreateTerrainWithSplat场景,另存为Tutor_5_CreateTerrainWithSplat2。
7.选中Manager,然后将Splats设置为4张并指定贴图。将Splat Alpha Maps设置为一张并指定为splatAlpha.psd
之后运行,发现新建的地形确实是按splatAlpha.psd里的色带分布。
【风宇冲】Unity3D教程宝典之地形


之后我们再进一步,再在Splats里加第5张贴图,那么该splat图就对应第二张splatAlpha图的红色。
8.photoShop里按上面的方法建张图,画个红色的竖条,并保存为splatAlpha2.psd
【风宇冲】Unity3D教程宝典之地形
9.选中Manager,然后将Splats设置为5张,指定第5张贴图。将Splat Alpha Maps设置为2并指定为之前的splatAlpha.psd和 splatAlpha2.psd

之后运行,效果如下
【风宇冲】Unity3D教程宝典之地形

三:地形与树
地形的绘制树功能十分强大,而且不仅可以绘制树,任意物体都可以都可以被当做树来铺在地形上。

(1)TreePrototypes
该步风宇冲用代码做总是出错,搜了也找不到解决方法,只好用地形编辑器来添加树的原型。现在把代码贴出来,
欢迎高手指出问题所在。
代码如下,unity显示在 terrainData.treePrototypes =  new   TreePrototype [ 1 ];这行有null
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEditor;

  4. public class Tutor_6_TreePrototype : MonoBehaviour {
  5. public GameObject treePrefab;
  6. public TerrainData terrainData;
  7. void Start()
  8. {
  9. CreateTerrain();
  10. }
  11. public Terrain CreateTerrain()
  12. {
  13. TerrainData  terrainData = new TerrainData();
  14. terrainData.heightmapResolution = 513;
  15. terrainData.baseMapResolution = 513;
  16. terrainData.size = new Vector3(50, 50, 50);
  17. terrainData.alphamapResolution = 512;
  18.      terrainData.SetDetailResolution(32, 8);
  19. TreePrototype treePrototype = new TreePrototype();
  20. treePrototype.prefab = treePrefab;
  21. treePrototype.bendFactor = 1;
  22. terrainData.treePrototypes = new TreePrototype[1];
  23. terrainData.treePrototypes[0] = treePrototype;
  24. GameObject obj = Terrain.CreateTerrainGameObject(terrainData);
  25. AssetDatabase.CreateAsset(terrainData, "Assets/Tutorial/Tutor_1_SimpleTerrain.asset");
  26.      AssetDatabase.SaveAssets();
  27. return  obj.GetComponent<</span>Terrain>();
  28. }
  29. }

 


(2)TreeInstances
TreeInstances
步骤:
1.创建TreeInstance
TreeInstance  tmpTreeInstances =  new TreeInstance();
2.设置TreeInstance属性

TreeInstance.prototypeindex:使用的prototype序号,从0开始

TreeInstance.position:在地形里的相对位置(不是世界坐标的位置),范围为[0,1]

TreeInstance.color:树的颜色

TreeInstance.lightmapColor:树如果有lightmap的话,lightmap的颜色

TreeInstance.heightScale:树高的缩放 即y轴上的缩放

TreeInstance.widthScale:树宽的缩放,即xz轴上的缩放

3.地形Terrain添加TreeInstance

Terrain terrain;

terrain.AddTreeInstance(tmpTreeInstances);

4.重设碰撞

TerrainCollider  tc = terrain.GetComponent();

tc.enabled = false;

tc.enabled = true;


例子:在整个地形上创建100个随机位置,大小为[0.8,1]间随机的树。脚本如下:

 

  1. using UnityEngine;
  2. using System.Collections;

  3. public class Tutor_6_TreeInstances : MonoBehaviour {
  4. public Terrain terrain;

  5. void Start () {
  6. AddTrees(terrain,100);
  7. }
  8. public void AddTrees(Terrain terrain,int numOfTrees)
  9. {
  10. if(terrain.terrainData!=null)
  11. {
  12. terrain.terrainData.treeInstances = new TreeInstance[numOfTrees];
  13. for(int i =0;i< numOfTrees;i++)
  14. {
  15. TreeInstance tmpTreeInstances = new TreeInstance();
  16. tmpTreeInstances.prototypeIndex =0; // ID of tree prototype
  17. tmpTreeInstances.position = new Vector3(Random.Range(0f,1f),0,Random.Range(0f,1f));   // not regular pos,  [0,1]
  18. tmpTreeInstances.color = new Color(1,1,1,1);
  19. tmpTreeInstances.lightmapColor = new Color(1,1,1,1);//must add
  20. float ss= Random.Range(0.8f,1f);
  21. tmpTreeInstances.heightScale =ss; //same size as prototype
  22. tmpTreeInstances.widthScale =ss;
  23. terrain.AddTreeInstance(tmpTreeInstances);
  24. }
  25. TerrainCollider  tc = terrain.GetComponent<</span>TerrainCollider>();
  26. tc.enabled = false;
  27. tc.enabled = true;
  28. }
  29. }
  30. } 

 结语:整个地形教程到此结束,希望对大家有所帮助。

转载自风宇冲Unity3D教程学院



  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值