Search Unity

Question Terrain generator [CODE EXAMPLE]

Discussion in 'World Building' started by fheronax, Mar 12, 2023.

  1. fheronax

    fheronax

    Joined:
    May 2, 2020
    Posts:
    13
    Hi all. I'm trying to write a tree generator for each terrain. How the terrain creation logic works:

    If the player approaches the boundary of a terrain, another terrain is created nearby.
    There is a problem with the placement of trees on the terrain.

    When a terrain with zero height is created, the trees keep the position of the previous terrain and are set to the new one.
    upload_2023-3-12_14-49-58.png

    I compared the position of the trees and the heights of the previous terrain and they are identical

    upload_2023-3-12_14-51-31.png

    Here is my code for creating trees


    Code (CSharp):
    1. for (int i = 0; i < numberOfTrees; i++)
    2.     {
    3.       TreeInstance tree = new TreeInstance();
    4.       tree.prototypeIndex = Random.Range(0, 2);
    5.       Vector3 randomRayPosition = new Vector3(Random.Range(terrain.transform.position.x, terrainData.size.x), 300, Random.Range(terrain.transform.position.z, terrainData.size.z));
    6.  
    7.       if (Physics.Raycast(randomRayPosition, Vector3.down, out TreeRayPoint))
    8.       {
    9.         tree.position = new Vector3(TreeRayPoint.point.x / terrainData.size.x, TreeRayPoint.point.y / terrainData.size.y, TreeRayPoint.point.z / terrainData.size.z);
    10.       }
    11.       Debug.DrawRay(TreeRayPoint.point, Vector3.down, Color.red, 100);
    12.       tree.widthScale = 1;
    13.       tree.heightScale = 1;
    14.  
    15.       treeInstances.Add(tree);
    16.     }
    The raycast collision with the terrain (I render it) works fine, everything collides where it needs to, but it doesn't set the trees in the correct position
     

    Attached Files:

  2. fheronax

    fheronax

    Joined:
    May 2, 2020
    Posts:
    13
    Here is all code for trees generator
    Code (CSharp):
    1.   void AddRandomTreesToTerrain()
    2.   {
    3.     terrainData.treePrototypes = new TreePrototype[0]; // reset tree prototypes
    4.     GameObject[] loadedAssets = Resources.LoadAll<GameObject>("Prefabs/Trees");
    5.     List<TreePrototype> treePrototypes = new List<TreePrototype>();
    6.  
    7.     foreach (GameObject tree in loadedAssets)
    8.     {
    9.       TreePrototype treePrototype = new TreePrototype();
    10.       treePrototype.prefab = tree;
    11.       treePrototypes.Add(treePrototype);
    12.     }
    13.  
    14.     terrainData.treePrototypes = treePrototypes.ToArray();
    15.  
    16.     RaycastHit TreeRayPoint;
    17.     List<TreeInstance> treeInstances = new List<TreeInstance>();
    18.     GameObject prefab = loadedAssets[0] as GameObject;
    19.  
    20.     for (int i = 0; i < numberOfTrees; i++)
    21.     {
    22.       TreeInstance tree = new TreeInstance();
    23.       tree.prototypeIndex = Random.Range(0, 2);
    24.       Vector3 randomRayPosition = new Vector3(Random.Range(terrain.transform.position.x, terrainData.size.x), 300, Random.Range(terrain.transform.position.z, terrainData.size.z));
    25.  
    26.       if (Physics.Raycast(randomRayPosition, Vector3.down, out TreeRayPoint))
    27.       {
    28.         tree.position = new Vector3(TreeRayPoint.point.x / terrainData.size.x, TreeRayPoint.point.y / terrainData.size.y, TreeRayPoint.point.z / terrainData.size.z);
    29.       }
    30.       Debug.DrawRay(TreeRayPoint.point, Vector3.down, Color.red, 100);
    31.       tree.widthScale = 1;
    32.       tree.heightScale = 1;
    33.  
    34.       treeInstances.Add(tree);
    35.     }
    36.  
    37.     terrainData.treeInstances = treeInstances.ToArray();
    38.  
    39.     terrain.Flush();
    40.   }
    41. }
    42.  
     
  3. fheronax

    fheronax

    Joined:
    May 2, 2020
    Posts:
    13
    Maybe I do not fully understand how to set the position for trees, I use this line

    Code (CSharp):
    1. tree.position = new Vector3(TreeRayPoint.point.x / terrainData.size.x, TreeRayPoint.point.y / terrainData.size.y, TreeRayPoint.point.z / terrainData.size.z);
    But I get this result

    upload_2023-3-12_15-2-1.png

    The trees are lined up along the y axis in a row, I don’t understand what’s wrong
     
  4. fheronax

    fheronax

    Joined:
    May 2, 2020
    Posts:
    13
    As soon as I asked a question here, I found the answer (as always) ... I just added after the line
    Code (CSharp):
    1. terrainData.treeInstances = treeInstances.ToArray();
    This line
    Code (CSharp):
    1. terrain.terrainData.SetTreeInstances(terrainData.treeInstances, true);