Search Unity

Remove trees from the terrain during runtime?

Discussion in 'Scripting' started by Velo222, May 1, 2013.

  1. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,437
    Hello,

    I have looked at several threads on how to remove a tree from a terrain (during the game), and I've written my own script. But I can't figure out why my script won't work. I should say that most of the examples are in C# (of course :rolleyes:), and I mainly use Javascript/Unityscript. But that aside, I still am at a loss as to why it's not working.

    Here is my script:

    Code (csharp):
    1. //#pragma strict
    2.  
    3. public var amountOfWood : int = 100;
    4.  
    5. //Tree array for the terrain data
    6. private var treeArray : TreeInstance[];
    7. private var treeArrayJS = new Array();
    8.  
    9. private var distance : float;
    10.  
    11. private var terrain : TerrainData;
    12. private var i : int;
    13. private var thisTransform : Transform;
    14.  
    15. //The closest tree's position
    16. private var closestTreePosition : float;
    17. //Nearest tree to the collider
    18. private var nearestTree : TreeInstance;
    19.  
    20.  
    21. function Start () {
    22.  
    23. thisTransform = transform;
    24. treeArray = Terrain.activeTerrain.terrainData.treeInstances;
    25.  
    26. treeArrayJS = new Array(treeArray);
    27. //Debug.Log(treeArrayJS.length);
    28.  
    29. terrain = Terrain.activeTerrain.terrainData;
    30.  
    31. }
    32.  
    33. function Update () {
    34.  
    35.  
    36.     if(amountOfWood <= 0) {
    37.    
    38.    
    39.                 // Our current closest tree initializes to far away
    40.                 var maxDistance : float = Mathf.Infinity;
    41.                
    42.                 for (i = 0; i < treeArrayJS.length; i++)
    43.                 {
    44.                     //Get the trees world position on the terrain
    45.                     var treePosition : Vector3 = Vector3.Scale(treeArrayJS[i].position, terrain.size);
    46.        
    47.                     //Check the distance between the tree collider and the tree's position
    48.                     closestTreePosition = (treePosition - thisTransform.position).sqrMagnitude;
    49.                
    50.                     if(closestTreePosition < maxDistance) {
    51.                         maxDistance = closestTreePosition;
    52.      
    53.                         nearestTree = treeArrayJS[i];
    54.                         //Debug.Log(nearestTree);
    55.                        
    56.                                    
    57.                                    
    58.                     }
    59.                
    60.                 }
    61.  
    62.                 // Remove the tree from the terrain tree list
    63.                 treeArrayJS.Remove(nearestTree);
    64.                 treeArray = treeArrayJS.ToBuiltin(TreeInstance) as TreeInstance[];
    65.    
    66.    
    67.     }
    68.  
    69.  
    70.  
    71. }  

    When this script executes, nothing happens. I don't get any errors, but nothing at all happens.

    Thanks for any help.
     
    Last edited: May 1, 2013
  2. wccrawford

    wccrawford

    Joined:
    Sep 30, 2011
    Posts:
    2,039
    Throw in some Debug.Log statements at key points to make sure you're even getting to them. If not, then figure out why.
     
  3. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,437
    When I debug.Log the Javascript array (after building it from the default treeInstances array), I get that there are 78 objects in the array. Which sounds right. 78 trees looks right to me as I look at my terrain.

    Then when I Debug.Log the nearestTree variable in the "for" loop, I get about 78 logs like this:
    UnityEngine.TreeInstance
    UnityEngine.Debug:Log(Object)
    ResourceHolder:Update() (at Assets/Scripts/ResourceHolder.js:54)


    I can't figure out why it won't remove the closest tree to "x".
     
  4. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,437
    Well I got it working thankfully. Took me about a day and a half to finally figure out why Unity no comprende, but thats why I hate and love programming lol.

    My main stumbling block was this line at the bottom of the script:
    Code (csharp):
    1. treeArray = treeArrayJS.ToBuiltin(TreeInstance) as TreeInstance[];
    For some reason, even though I referenced the actual treeInstance array at start, I actually had to "manually" reference it like this:
    Code (csharp):
    1. Terrain.activeTerrain.terrainData.treeInstances = treeArrayJS.ToBuiltin(TreeInstance) as TreeInstance[];
    And then it worked. Why? I have no idea. Syntax wins again.

    45 trial and error runs later..........:eek::-x
     
  5. wccrawford

    wccrawford

    Joined:
    Sep 30, 2011
    Posts:
    2,039
    Weird. Glad you got it sorted!
     
  6. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    It's because object variables in JS (and mostly in C#) are "references", basically a thing which points to something else. Your "treeArray" variable is a different reference than Terrain.activeTerrain.terrainData.treeInstances. They are two different references both pointing to the same thing. When you reassign treeArray you make it point to a different array, but it doesn't make Terrain.activeTerrain.terrainData.treeInstances point to it.