Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Destroyable Trees

Discussion in 'Made With Unity' started by Tom163, Aug 20, 2009.

  1. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,290
    A friend of mine (Martin/Decane) asked for it...

    Building on my work with procedural landscapes and vegetations (see http://forum.unity3d.com/viewtopic.php?t=30587), I thought now that I have the trees accessible by script, one can do funny things to them.

    Like, you know, blow them up:
     

    Attached Files:

    Kos-Dvornik likes this.
  2. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,290
  3. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,290
    And here's the code that does it all. Attach to the source of your explosion, trigger it however you want it triggered, blow up some trees. :)


    Right now, it uses the same dead replacement for all trees. Obviously, for an actual game you would want to use an array of dead replacements, and then simply use tree.prototypeIndex as the index for your array.

    The dead tree must have a collider and a rigidbody attached, otherwise it won't fall correctly.

    You also need to attach an explosion prefab.

    Play with BlastRange and BlastForce to tune the effect. I'm sure you can also improve lots of other things, this script is just a proof-of-concept to show how it's done.
     

    Attached Files:

    esustachah, Skunk-Software and jojue like this.
  4. Martin-Schultz

    Martin-Schultz

    Joined:
    Jan 10, 2006
    Posts:
    1,377
    Haha, way cool, that rocks!!! :)
     
  5. jaxas

    jaxas

    Joined:
    Mar 22, 2009
    Posts:
    59
    hmm, it looks not realistic, maybe you should just pull down tree, not push it :?:
     
  6. raoul

    raoul

    Joined:
    Jul 14, 2007
    Posts:
    6,722
    Jaxas, I guess this is more intended like a prototype. Great stuff Tom! Also liked your other post about dynamic trees a lot, thanks for sharing that script!
     
  7. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,290
    Yes, it's a demo to show that and how it can be done.

    You're welcome to add a better explosion effect, extend the replacement action (if the branches would break off, for example, the would be great) and of course fix the force and falling-down effect. I thought about a joint at the root so the tree just topples over, etc.

    Feel free. I hope I've solved some of the more trickier problems and the rest can be done according to what your game requires.


    Oh, one more thing: If you test things in the editor when using this, be beware that any changes to trees (i.e. tree removal) is permanent and will not be undone when you exit the game.
     
  8. Alec

    Alec

    Joined:
    Mar 11, 2008
    Posts:
    1,330
    Cool.
     
  9. half_voxel

    half_voxel

    Joined:
    Oct 20, 2007
    Posts:
    978
    SO Coool!!
     
  10. supershwa

    supershwa

    Joined:
    Feb 10, 2013
    Posts:
    12
    Excellent script. I'm using JS, and was easily able to convert to (basically):

    Code (csharp):
    1.  
    2.     var terrain = Terrain.activeTerrain.terrainData;
    3.     var instances = new ArrayList();
    4.     var blastRange = 10.0;
    5.     var DeadReplace : GameObject;
    6.    
    7.    
    8.     for (var tree in terrain.treeInstances) {
    9.         var distance = Vector3.Distance(Vector3.Scale(tree.position, terrain.size) + Terrain.activeTerrain.transform.position, transform.position);
    10.         if(distance<blastRange) {
    11.             //kill the tree
    12.             var deadTree = Instantiate(DeadReplace, Vector3.Scale(tree.position, terrain.size) + Terrain.activeTerrain.transform.position, Quaternion.identity) as GameObject;
    13.             DeadReplace.rigidbody.maxAngularVelocity = 1;
    14.             DeadReplace.rigidbody.AddExplosionForce(100, transform.position, blastRange*5, 0.0);
    15.         } else {
    16.             instances.Add(tree);
    17.         }
    18.     }
    19.     terrain.treeInstances = instances.ToArray(typeof(TreeInstance));
    20.  

    I use a separate function to instantiate the particle system prefab "explosion"...this is not copy/paste, either -- you need to use a public "DeadReplace" var in your script to define the necessary "dead tree" object in the explorer. But a general JS translation for those who need it.

    Works great, though -- my terrain trees are dying!
     
  11. Cowboykilla

    Cowboykilla

    Joined:
    May 17, 2013
    Posts:
    5
    OMG! THANK YOU SOOOOOOOOOOO MUCH! You have no idea how much you've helped me with this :)
     
  12. RoloJo

    RoloJo

    Joined:
    Feb 26, 2013
    Posts:
    28
    Thanks so much for the script; it was really helpful. Unfortunately, with this script the colliders remain. You can use the SetHeights function to remove the colliders also, however, as I am using it creates a significant delay. The line of code I am using is:

    terrain.terrainData.SetHeights(0, 0, new float[,] { { } });

    As I understand it this is setting the heights for the entire terrain. Could anyone help me in understanding what the input variables to SetHeights mean and what their ranges are. This would help me to only update the specific tile/zone where the tree was removed.

    THANKS!
     
  13. cgeopapa

    cgeopapa

    Joined:
    Sep 23, 2014
    Posts:
    23
    I know this an old thread but hopefully someone will answer me...
    I cant understand why the trees are destroying themselves. I mean witch is the line of code that gives this command?
     
  14. mb28

    mb28

    Joined:
    Oct 7, 2012
    Posts:
    27
    Basically the script iterates through all the trees in your terrain and then if they are within the blast radius, they get replaced. In the C# example, this is the line of code that is replacing the trees with the destroyed ones.

    Code (CSharp):
    1. instanceTData.treeInstances = (TreeInstance[])instances.ToArray(typeof(TreeInstance));
    Now if you want, an addition to this code is to instantiate your terrain and its data. Then use that instantiated version to remove trees. This way, when you stop the runtime, you won't lose any of your original terrain data. Here's what I did and you're welcome to use it. You may have to adjust variable names to your liking.

    Code (CSharp):
    1.     public GameObject primaryTerrain;
    2.     public TerrainData primaryTData;
    3.  
    4.     private GameObject instanceTerrain;
    5.     private TerrainData instanceTData;
    6.  
    7.     void Start()
    8.     {
    9.         //instantiate the terrain data
    10.         instanceTData = Instantiate(primaryTData);
    11.         //create a new terrain object using the instantiated terrain data
    12.         instanceTerrain = Terrain.CreateTerrainGameObject(instanceTData);
    13.  
    14.         Vector3 position = new Vector3(0,0,0);
    15.         //getting the component of my original terrain so I can disable it.  We don't need two identical terrains in the scene
    16.         Terrain terrain = primaryTerrain.GetComponent<Terrain>();
    17.         terrain.enabled = false;
    18.  
    19.  
    20.     }
    There are two public variables, one for the terrain I'm going to instantiate, and one for the data related to that particular terrain. I already had a completed terrain, so I could just drag and drop my terrain and its data onto my script.

    Now throughout your script, you can reference instanceTData for your instanced terrain data and instanceTerrain for the terrain game object. Hope this helps.
     
    Skunk-Software and jojue like this.
  15. mb28

    mb28

    Joined:
    Oct 7, 2012
    Posts:
    27
    Check out my other post in this thread. Sorry, forgot to reply directly to your post. You can instantiate the terrain so it preserves the original
     
  16. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,290
    Mother of all necros :)

    But thanks to mb28 for the addition, this solves the engine problem of permance of changes, very nice.
     
    jojue and mb28 like this.