Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

how to add trees to terrain based on texture

Discussion in 'Scripting' started by ar333, Mar 25, 2016.

  1. ar333

    ar333

    Joined:
    Jul 26, 2014
    Posts:
    14
    Hi everyone, i finished making a script to generate a terrain from libNoise, auto texture with another script to add textures based on height and slope, and one for grass generation.
    2016-03-25 20_21_54-Photos.png


    I'v been trying to add trees to my terrain based on the texture on the ground, but don't know what i have to use for this...

    If anyone already did something similar, it would be great if you can help!
     
  2. AlucardJay

    AlucardJay

    Joined:
    May 28, 2012
    Posts:
    328
  3. ar333

    ar333

    Joined:
    Jul 26, 2014
    Posts:
    14
    Thanks for the reply, oh and those tutorials you did a while back for the libnoise helped a lot!
    Cool, what exactly can your tools do?
     
    Last edited: Mar 25, 2016
  4. ar333

    ar333

    Joined:
    Jul 26, 2014
    Posts:
    14
    Can't get the trees placed on the specific splat texture which is the 2nd texture of 3...
    2016-03-26 11_29_3199-Photos.png
    Could you give an example of random placement on only that texture?
    Any help is appreciated thanks!

    Using this to place objects and trees randomly... but cant get the objects placed on the areas with specific splat textures..

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class RandomObjects : MonoBehaviour
    4. {
    5.     public Terrain terrain;
    6.     public int numberOfObjects; // number of objects to place
    7.     private int currentObjects; // number of placed objects
    8.     public GameObject objectToPlace; // GameObject to place
    9.     private int terrainWidth; // terrain size (x)
    10.     private int terrainLength; // terrain size (z)
    11.     private int terrainPosX; // terrain position x
    12.     private int terrainPosZ; // terrain position z
    13.     void Start()
    14.     {
    15.         terrain = gameObject.GetComponent<Terrain> ();
    16.         // terrain size x
    17.         terrainWidth = (int)terrain.terrainData.size.x;
    18.         // terrain size z
    19.         terrainLength = (int)terrain.terrainData.size.z;
    20.         // terrain x position
    21.         terrainPosX = (int)terrain.transform.position.x;
    22.         // terrain z position
    23.         terrainPosZ = (int)terrain.transform.position.z;
    24.  
    25.         for (int t =0; t <50; t++){
    26.  
    27.             if(currentObjects <= numberOfObjects)
    28.             {
    29.                 // generate random x position
    30.                 int posx = Random.Range(terrainPosX, terrainPosX + terrainWidth);
    31.                 // generate random z position
    32.                 int posz = Random.Range(terrainPosZ, terrainPosZ + terrainLength);
    33.                 // get the terrain height at the random position
    34.                 float posy = Terrain.activeTerrain.SampleHeight(new Vector3(posx, 0, posz));
    35.                 // create new gameObject on random position
    36.                 GameObject newObject = (GameObject)Instantiate(objectToPlace, new Vector3(posx, posy, posz), Quaternion.identity);
    37.                 currentObjects += 1;
    38.             }
    39.             if(currentObjects == numberOfObjects)
    40.             {
    41.                 Debug.Log("Generate objects complete!");
    42.             }
    43.         }
    44.  
    45.     }
    46.     // Update is called once per frame
    47.     void Update()
    48.     {
    49.         // generate objects
    50.  
    51.     }
    52. }
     
    Last edited: Mar 26, 2016
  5. AlucardJay

    AlucardJay

    Joined:
    May 28, 2012
    Posts:
    328
    Couple of observations:
    The for-loop with a hard-coded value. This should use numberOfObjects instead of 50.
    Although the variables currentObjects and numberOfObjects could be used in a while-loop, checking if the random site is feasible and if there is no tree assigned there already:
    Code (csharp):
    1. while( currentObjects < numberOfObjects )
    2. {
    3.    // get random site
    4.    // if site is feasible(texture index and slope angle), and site has no tree already, add tree and currentObjects++;
    5. }
    6. Debug.Log("Generate objects complete!");
    line 34: using Terrain.activeTerrain, but you already have a reference to the terrain on line 15
    Code (csharp):
    1. float posy = terrain.SampleHeight(new Vector3(posx, 0, posz));
    Regarding checking the random tree position terrain texture index:
    As you are using world-space coordinates for tree position, simply pass that to the GetMainTexture function
    Code (csharp):
    1. int terrainTextureIndexToPlaceTreeOn = 1; // specific splat texture which is the 2nd texture of 3...
    2. Vector3 randomTreePos = new Vector3( posx, posy, posz );
    3. int textureIndexAtRandomTreePos = GetMainTexture( randomTreePos );
    4.  
    5. if ( textureIndexAtRandomTreePos == terrainTextureIndexToPlaceTreeOn )
    6. {
    7.    // should also check if there is not a tree there already
    8.    Add Tree Object
    9.    currentObjects++;
    10. }

    Personally I think for you a better approach would be to: create a list of all possible tree sites; then choose random values from that list to place trees

    Code (csharp):
    1. // create a list of all possible sites
    2. List< Vector3 > possibleTreeSites = new List< Vector3 >();
    3. // using your method of integers within the terrain width and length
    4. for ( int x = 0; x < terrainWidth; x++ )
    5. {
    6.    for ( int z = 0; z < terrainLength; z++ )
    7.    {
    8.      Vector3 checkPos = new Vector3( terrainPosX + x, 0, terrainPosZ + z );
    9.      int textureIndexAtCheckPos = GetMainTexture( checkPos );
    10.      // consider also checking the slope angle
    11.  
    12.      if ( textureIndexAtCheckPos == terrainTextureIndexToPlaceTreeOn )
    13.      {
    14.        possibleTreeSites.Add( checkPos );
    15.      }
    16.    }
    17. }
    18.  
    19. // now you have a list of all possible sites, draw 50(numberOfObjects) values from that list to place a tree
    20.  
    21. // first check there are enough positions in the list
    22. if ( numberOfObjects > possibleTreeSites.Count )
    23. {
    24.    numberOfObjects = possibleTreeSites.Count;
    25. }
    26.  
    27. // now loop, draw random values and place tree
    28. for ( int t = 0; t < numberOfObjects; t++ )
    29. {
    30.    // get random index of possibleTreeSites
    31.    int randomIndex = Random.Range( 0, possibleTreeSites.Count );
    32.  
    33.    // get Y-value for position
    34.    Vector3 treeSite = possibleTreeSites[ randomIndex ]; // <- EDIT: fixed incorrect brackets
    35.    float posY = terrain.SampleHeight( treeSite );
    36.    treeSite.y = posY;
    37.  
    38.    // place tree
    39.    GameObject newObject = (GameObject)Instantiate(objectToPlace, treeSite, Quaternion.identity);
    40.  
    41.    // remove that site from the list!!
    42.    possibleTreeSites.RemoveAt( randomIndex );
    43. }
    Please note this code is just a pseudo-example so you don't repeat random sites.

    Regarding your query about my terrain tools:
    Currently working on:

    Copy Terrain : select resolution; heightmap; textures; splatmap; details; detailmap; trees; treedata
    Paint By Slope Angles : currently only for exactly 4 textures
    Mass Place Trees : select count; slope angle; water level(no underwater trees)
    Grass Around Trees : places grass around trees. select radius; slope angle; density; density falloff
    Grass On Texture : density based on slope angle using curves

    Still need to clean up some stuff, then make videos showing how they work. Shall post the link when complete :)
     
    Last edited: Mar 27, 2016
    MaximilianPs likes this.
  6. ar333

    ar333

    Joined:
    Jul 26, 2014
    Posts:
    14
    Thanks will try this code when i get home!
    Nice, all the features i'v been trying to make for a terrainGen script..
    You going to put it on the asset store?
     
  7. ar333

    ar333

    Joined:
    Jul 26, 2014
    Posts:
    14
    =
    error CS0119: Expression denotes a `variable', where a `method group' was expected
    Not sure what to make of this...
     
  8. AlucardJay

    AlucardJay

    Joined:
    May 28, 2012
    Posts:
    328
    That's a typo, sorry. I wrote the pseudocode in notepad++, so untested.
    Code (csharp):
    1. Vector3 treeSite = possibleTreeSites[ randomIndex ];
    Accessing an array(well, a list, a type of collection), not a function. Note the square brackets.
    I have fixed the other post.

    Edit: I hope you see what is happening in that example.
    A list of all possible tree sites is made.
    Then a loop for the desired number of trees, where a random position in that list is selected.
    That line is getting a value from that random position in the list.

    Not going to put my stuff on the asset store, it'll be free on my 'site (maybe I'll publish here too).
     
    Last edited: Mar 27, 2016
  9. ar333

    ar333

    Joined:
    Jul 26, 2014
    Posts:
    14
    You Sir... are a Genius!!:D

    Already fixed slope and water issue in another script will just add them together later....
    But the texture spawn issue is 100% Gone!:)
    2016-03-28 01_33_58-New notification1111.png

    THANKS a lot!
     
  10. ar333

    ar333

    Joined:
    Jul 26, 2014
    Posts:
    14
    What is your website address?
     
  11. Hassaan-XD

    Hassaan-XD

    Joined:
    Jul 18, 2015
    Posts:
    14
    Hey man, I need your help. I am not a scripting guy, just a simple level designer. I am learning some world designing skills. Do you have this script working? Does it place specific tree on specific texture? I exactly need that thing, but cannot find anywhere else. So please, could you give me the working script? I'll be really thankful!
     
  12. purnamasari

    purnamasari

    Joined:
    Mar 8, 2018
    Posts:
    17

    Could you please show us how you achieve grass generation? It would be so helpful for me. Thanks!