- Home /
 
Procedural Tree Placement using perlin noise
I have made a procedural terrain generation in unity using some tutorials but i cant figure out how i can randomly place trees on my terrain and i couldnt find anything on the internet. So how can i randomly place trees using perlin noise on a procedural terrain?
Answer by ShadyProductions · Feb 14, 2018 at 06:40 PM
Usually what I do is i loop over my map that I have in memory and if i'm on a tile that can inhabit a tree i put a random chance to put a tree there, After that algorithm is done the map has random trees but its kinda ugly, So I use something called Cellular Automata to remove all tree's that aren't grouped (all tiles that don't have more than 3 neighbors of same tree). After that you end up with dense forests of tree's, depending on your chances.
Here is an example (without rendering):
 using System.Collections.Generic;
 using System.Linq;
 using UnityEngine;
 
 namespace Assets.Scripts
 {
     public class MapGeneration : MonoBehaviour
     {
         private const int mapSize = 25;
         private int[,] map;
 
         private void Start()
         {
             // Setup the array
             map = new int[mapSize, mapSize];
 
             // Populate map with some random types between 1 - 4
             PopulateMap();
 
             // will replace all type 2 with type 3
             // if the type 2 tile does not have more than 2 neighbors of the same type.
             // This will give you a grouped effect of the given type
             // parameters: tile, replacement, minAlive
             ApplyCellularAutomationMin(2, 3, 2); 
 
             // rendering of the map
             // .....
         }
 
         private void PopulateMap()
         {
             System.Random rand = new System.Random();
             for (int x=0; x < mapSize; x++)
             {
                 for (int y = 0; y < mapSize; y++)
                 {
                     map[x, y] = rand.Next(5); // Set a random type between 1 - 4
                 }
             }
         }
 
         private int GetTile(int x, int y)
         {
             // Get the tile type or -1 if outside of bounds
             return (x > map.GetUpperBound(0) || y > map.GetUpperBound(1) || x < 0 || y < 0) ? -1 : map[x, y];
         }
 
         private IEnumerable<int> GetNeighbors(int x, int y)
         {
             // Each tile has 8 neighbors
             var neighbors = new int[8];
 
             // Get each neighbor based on the tile position x, y
             neighbors[0] = GetTile(x - 1, y);
             neighbors[1] = GetTile(x, y - 1);
             neighbors[2] = GetTile(x - 1, y - 1);
             neighbors[3] = GetTile(x + 1, y);
             neighbors[4] = GetTile(x, y + 1);
             neighbors[5] = GetTile(x + 1, y + 1);
             neighbors[6] = GetTile(x - 1, y + 1);
             neighbors[7] = GetTile(x + 1, y - 1);
 
             // Exclude -1 tiles because those are unexisting ones returned by GetTile
             return neighbors.Where(f => f != -1);
         }
 
         private void ApplyCellularAutomationMin(int tile, int replacementTile, int minAlive)
         {
             // Perform twice to cleanup residue of automation
             for (int i = 0; i < 2; i++)
             {
                 for (int x = 0; x < map.GetLength(0); x++)
                 {
                     for (int y = 0; y < map.GetLength(1); y++)
                     {
                         // Get only the neighbors where the type is the given tile.
                         var neighbors = GetNeighbors(x,y).Where(f => f == tile);
                         // If there are not enough alive, then replace the tile.
                         if (neighbors.Count() < minAlive)
                         {
                             map[x, y] = replacementTile;
                         }
                     }
                 }
             }
         }
     }
 }
 
              Your answer
 
             Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Unexpected period length with Unity Mathematics pnoise method 0 Answers
Mesh generation issue (C#) 1 Answer
How to add erosion to terrain on runtime 0 Answers