Функция посадки дерева:
//добавляем новое дерево
public void CreateNewTree(){
float qualityNew=(1 + Random.Range(-0.2f,0.2f))*qualityMiddle;
if (qualityNew>1f){
GameObject newTree = Instantiate(tree,Vector3.zero, Quaternion.identity);
TreeUp treeUp = newTree.GetComponent<TreeUp>();
PropObject propObj = newTree.GetComponent<PropObject>();
treeUp.setScale(new Vector3(0.01f,0.01f,0.01f));//задаем начальный масштаб
newTree.transform.SetParent(forest.transform); //помещаем в родителя
newTree.name = "tree"+Component.FindObjectOfType<WorldTime>().getWorldTime(); // меняем имя
newTree.GetComponent<CapsuleCollider>().radius = treeColliderRadius;
propObj.timeLife = (1 + Random.Range(-0.2f,0.2f))*timeLife; //рандомизация на 20% время жизни нового объекта
propObj.quality = qualityNew; //рандомизация качества дерева
int numTerrain=-1;
float alpha=0f;
Vector3 newDir = Vector3.zero;
do{
//Выбираем случайные интервалы посадки
newDir = new Vector3(Random.Range((minX-10f),(maxX+10f)),transform.position.y,Random.Range((minZ-10f),(maxZ+10f)));
numTerrain = _Global.inTerrains(newDir);
if (numTerrain>=0){
alpha = _Global.GetAlphaLayerInVector3(newDir, "Grass");
}
}
while(numTerrain<0 || alpha<0.9f);
float h = Terrain.activeTerrains[numTerrain].SampleHeight(newDir);
newDir.y = h; //вкапываем дерево - 0.2f
newTree.GetComponent<Transform>().position = newDir;
getMiddleTreesInfo();
}
Функция определения номера terrain по координатам:
//нахождение объекта на terrain
public static int inTerrains(Vector3 obj){
Terrain[] terrains = Terrain.activeTerrains;
for (int i = 0; i < terrains.Length; i++)
{
if (
(obj.x >= terrains[i].transform.position.x) && ( obj.x <= (terrains[i].transform.position.x + terrains[i].terrainData.size.x ))
&& (obj.z >= terrains[i].transform.position.z) && ( obj.z <= (terrains[i].transform.position.z + terrains[i].terrainData.size.z ))
){
return i;
}
}
return -1;
}
Функция определения альфа канала определенного слоя в указанной точке:
public static float GetAlphaLayerInVector3(Vector3 vector, string layerName){
float alphaResult=0f;
int numTerrain = _Global.inTerrains(new Vector3(vector.x, 0f, vector.z));
if (numTerrain==-1){return alphaResult;}
Terrain terrain = Terrain.activeTerrains[numTerrain];
TerrainData terrainData = terrain.terrainData;
int res = terrainData.heightmapResolution; //разрешение
float[,,] alpha = terrainData.GetAlphamaps(0,0,terrainData.alphamapWidth,terrainData.alphamapHeight);
int Xi = (int) (vector.x * terrainData.heightmapResolution / terrainData.size.x);
int Zi = (int) (vector.z * res / terrainData.size.z);
int layerCnt = terrainData.alphamapLayers; //всего слоев
for (int i = 0; i < layerCnt; i++){
if (terrainData.terrainLayers[i].name == layerName){
alphaResult= alpha[Zi, Xi, i];
}
}
return alphaResult;
}
Видео обзор: