void UpdatePropLayer(TerrainImport terrainImport, TerrainImport.PropLayer layer) { var time = stopwatch.Elapsed; var terrain = terrainImport.GetComponent <Terrain>(); var terrainData = terrain.terrainData; if (layer.propSet == null) { return; } var instanceList = new List <TreeInstance>(terrainData.treeInstances); foreach (var propData in layer.propSet.props) { sampler.Setup(new float2(terrainData.size.x, terrainData.size.z), Mathf.Min(propData.distanceStart, propData.distanceEnd)); if (layer.map != null) { float[,] mapData = new float[layer.map.width, layer.map.height]; ReadChannelFromTexture(layer.map, 0, ref mapData); sampler.MapDesity(ref mapData, propData.minDensity, propData.maxDensity, propData.distanceStart, propData.distanceEnd); } sampler.Calculate(); var protoIndex = FindTreeProtoIndex(terrainData, propData.prefab); if (protoIndex == -1) { var protoList = new List <TreePrototype>(terrainData.treePrototypes); protoIndex = protoList.Count; protoList.Add(new TreePrototype { prefab = propData.prefab }); terrainData.treePrototypes = protoList.ToArray(); EditorUtility.SetDirty(terrainData); EditorUtility.SetDirty(terrain); } for (int i = 0; i < sampler.propData.Count; i++) { var prop = sampler.propData[i]; var gridData = sampler.propGrid[prop.gridIndex]; var pos3D = new Vector3(prop.pos.x, 0, prop.pos.y); var worldPos = terrainImport.transform.TransformPoint(pos3D); var height = terrain.SampleHeight(worldPos); var pos = new float3(sampler.propData[i].pos.x / terrainData.size.x, height / terrainData.size.y, sampler.propData[i].pos.y / terrainData.size.z); var densityFactor = 1.0f / (propData.maxDensity - propData.minDensity); var scaleRange = propData.scaleEnd - propData.scaleStart; var scale = propData.scaleStart + (gridData.density - propData.minDensity) * densityFactor * scaleRange; scale = scale + Random.Range(0, scale * propData.scaleRandomFraction); instanceList.Add(new TreeInstance { prototypeIndex = protoIndex, widthScale = scale, heightScale = scale, rotation = Random.Range(0, 360), color = propData.color, lightmapColor = propData.lightmapColor, position = pos }); } } terrainData.treeInstances = instanceList.ToArray(); EditorUtility.SetDirty(terrainData); EditorUtility.SetDirty(terrain); GameDebug.Log("Prop layers applied [" + (stopwatch.Elapsed - time).Milliseconds + "ms]"); }