• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by ReginTheSmith · Apr 14, 2021 at 05:34 PM · colliderterrain3ddestroytrees

Destroy Terrain trees and their colliders.

Destroy Terrain Trees And Their Collider ok so in my game I have a mechanic where you can chop down trees using a script attached to the player and one on a game manager object but the trees are painted into the terrain so they are hard to access. These scripts sort of work but the collider stays. so the tree mesh is gone but you can still collide with it. t$$anonymous$$s is the method I use for destroying the trees

 public void RemoveATrees(int index)
      {
          // remove a specific tree by index
          List<TreeInstance> instancesTmp = new List<TreeInstance>();
          int i = 0;
          foreach (TreeInstance tree in terrain.terrainData.treeInstances)
          {
              // loop a all of a tree on terrain
              if (i != index)
              {
                  // basically add every tree to a Tmp array, Except a tree with a specfic index
                  instancesTmp.Add(tree);
              }
              i++;
          }
          // replace a tree instances in terrain data with a Tmp array
          terrain.terrainData.treeInstances = instancesTmp.ToArray();
          // refresh the terrain, get rid of collider of that tree.
          float[,] heights = terrain.terrainData.GetHeights(0, 0, 0, 0);
          terrain.terrainData.SetHeights(0, 0, heights);
  
      }
  }

but the collider still stays. So does any one know how to fix t$$anonymous$$s?

also if you want both scripts here: On the player:

 using UnityEngine; using System.Collections; using System.Collections.Generic;
  // Purpose: demonstrate script interface to interact with terrain trees
  
  // Steps: Attach t$$anonymous$$s to main(parent/top) Player gameObject, or adjust myTransform to your $$anonymous$$erarchy,
  // define Inspector values for harvestTreeDistance, respawnTimer
  // Setup a prefab tree with CAPSULE collider, how to at bottom of
  // http://docs.unity3d.com/Documentation/Components/terrain-Trees.html
  // paint terrain tree 
  
  // Assign the non-collider prefab version of the tree to felledTree
  // press Play, left click on terrain tree
  
  // Harvested terrain tree info is passed to a manager object QM_ResourceManager for respawn management,
  // you'll need that too or you could comment out any functionality related to manager 
  
  // Note: t$$anonymous$$s is not a demo of modifying terrainData permanently - there's enough risk involved with that
  // such that you shouldn't try it unless you know what you are doing.
  
  
  public class QM_HarvestTerrainTree : MonoBehaviour
  {
  
      // Player, Range
      public int harvestTreeDistance;        // Set [Inspector] min. distance from Player to Tree for your scale?
      public bool rotatePlayer = true;    // Should we rotate the player to face the Tree? 
      private Transform myTransform;        // Player transform for cache
  
      // Terrains, Hit
      private Terrain terrain;            // Derived from $$anonymous$$t...GetComponent<Terrain>
      private RaycastHit $$anonymous$$t;                // For $$anonymous$$t. methods
      private string lastTerrain;            // To avoid reassignment/GetComponent on every Terrain click
  
      // Tree, GameManager
      public GameObject felledTree;        // Prefab to spawn at terrain tree loc for TIIIIIIMBER!
      private QM_ResourceManager rMgr;    // Resource manager script
      public float respawnTimer;            // Duration of terrain tree respawn timer
  
      void Start()
      {
  
          if (harvestTreeDistance <= 0)
          {
              Debug.Log("harvestTreeDistance unset in Inspector, using value: 6");
              harvestTreeDistance = 6;
          }
  
          if (respawnTimer <= 0)
          {
              Debug.Log("respawnTimer unset in Inspector, using quick test value: 15");
              respawnTimer = 15;
          }
  
          myTransform = transform;
          lastTerrain = null;
          rMgr = FindObjectOfType<QM_ResourceManager>();
  
      }
  
  
      void Update()
      {
  
          if (Input.GetMouseButtonUp(0))
          {
  
              Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
              if (Physics.Raycast(ray, out $$anonymous$$t, 30f))
              {
  
                  // Did we click a Terrain?
                  if ($$anonymous$$t.collider.gameObject.GetComponent<Terrain>() == null)
                      return;
  
                  // Did we click on the same Terrain as last time (or very first time?)
                  if (lastTerrain == null || lastTerrain != $$anonymous$$t.collider.name)
                  {
                      terrain = $$anonymous$$t.collider.gameObject.GetComponent<Terrain>();
                      lastTerrain = terrain.name;
                  }
  
                  // Was it the terrain or a terrain tree, based on SampleHeight()
                  float groundHeight = terrain.SampleHeight($$anonymous$$t.point);
  
                  if ($$anonymous$$t.point.y - .2f > groundHeight)
                  {
  
                      // It's a terrain tree, check Proximity and Harvest
                      if (CheckProximity())
                          HarvestWood();
  
                  }
              }
          }
      }
  
  
      private bool CheckProximity()
      {
          bool inRange = true;
          float clickDist = Vector3.Distance(myTransform.position, $$anonymous$$t.point);
  
          if (clickDist > harvestTreeDistance)
          {
              Debug.Log("Out of Range");
              inRange = false;
          }
  
          return inRange;
  
      }
  
      private bool CheckRecentUsage(string _terrainName, int _treeINDEX)
      {
          bool beenUsed = false;
  
          for (int cnt = 0; cnt < rMgr.managedTrees.Count; cnt++)
          {
              if (rMgr.managedTrees[cnt].terrainName == _terrainName && rMgr.managedTrees[cnt].treeINDEX == _treeINDEX)
              {
                  Debug.Log("Tree has been used recently");
                  beenUsed = true;
              }
          }
  
          return beenUsed;
      }
  
  
      private void HarvestWood()
      {
          int treeIDX = -1;
          int treeCount = terrain.terrainData.treeInstances.Length;
          float treeDist = harvestTreeDistance;
          Vector3 treePos = new Vector3(0, 0, 0);
  
          // Notice we are looping through every terrain tree, 
          // w$$anonymous$$ch is a caution against a 15,000 tree terrain
  
          for (int cnt = 0; cnt < treeCount; cnt++)
          {
              Vector3 t$$anonymous$$sTreePos = Vector3.Scale(terrain.terrainData.GetTreeInstance(cnt).position, terrain.terrainData.size) + terrain.transform.position;
              float t$$anonymous$$sTreeDist = Vector3.Distance(t$$anonymous$$sTreePos, $$anonymous$$t.point);
  
              if (t$$anonymous$$sTreeDist < treeDist)
              {
                  treeIDX = cnt;
                  treeDist = t$$anonymous$$sTreeDist;
                  treePos = t$$anonymous$$sTreePos;
              }
          }
  
  
          if (treeIDX == -1)
          {
              Debug.Log("Out of Range");
              return;
          }
  
          if (!CheckRecentUsage(terrain.name, treeIDX))
          {
  
  
  
              // Success - all tests passed
              // Place a cube to show the tree, the ResourceManager will remove it after a time
              // Obviously tweak to your liking, just a visual aid to show it worked
  
              RemoveATrees(treeIDX);
                  
  
  
             
  
              // Example of spawning a placed tree at t$$anonymous$$s location, just for demo purposes
              // it will slide through terrain and disappear in 4 seconds
              GameObject fellTree = Instantiate(felledTree, treePos, Quaternion.identity) as GameObject;
              
  
             
  
              // Add t$$anonymous$$s terrain tree and cube to our Resource Manager for demo purposes
              //rMgr.AddTerrainTree(terrain.name, treeIDX, Time.time + respawnTimer, marker.transform);
  
              if (rotatePlayer)
              {
                  Vector3 lookRot = new Vector3($$anonymous$$t.point.x, myTransform.position.y, $$anonymous$$t.point.z);
                  myTransform.LookAt(lookRot);
              }
  
              // There are too many guesses to be made here about your game mechanics to code the rest
              // For example, you might..
  
              // Start Animation
              // Play Sound Clip
              // Give player an Inventory item
              // Bump lumberjacking skill
              // Random.Range[] spawn a Forest Protector Spirit of Woe
              // etc.
  
          }
  
      }
      public void RemoveATrees(int index)
      {
          // remove a specific tree by index
          List<TreeInstance> instancesTmp = new List<TreeInstance>();
          int i = 0;
          foreach (TreeInstance tree in terrain.terrainData.treeInstances)
          {
              // loop a all of a tree on terrain
              if (i != index)
              {
                  // basically add every tree to a Tmp array, Except a tree with a specfic index
                  instancesTmp.Add(tree);
              }
              i++;
          }
          // replace a tree instances in terrain data with a Tmp array
          terrain.terrainData.treeInstances = instancesTmp.ToArray();
          // refresh the terrain, get rid of collider of that tree.
          float[,] heights = terrain.terrainData.GetHeights(0, 0, 0, 0);
          terrain.terrainData.SetHeights(0, 0, heights);
  
      }
  }

and on the game manager object:

 using UnityEngine;
  using System.Collections;
  using System.Collections.Generic;
  
  // Attach t$$anonymous$$s to a Singleton-like GameObject of w$$anonymous$$ch there is only and will ever only be one,
  // ala classic GameManager object.
  
  public class QM_ResourceManager : MonoBehaviour
  {
  
      // Define List component
      public class QM_Tree
      {
          public string terrainName { get; set; }
          public int treeINDEX { get; set; }
          public float respawnTime { get; set; }
          public Transform marker { get; set; }
  
          // Constructor
          public QM_Tree(string _terrainName, int _treeINDEX, float _respawnTime, Transform _marker)
          {
              terrainName = _terrainName;
              treeINDEX = _treeINDEX;
              respawnTime = _respawnTime;
              marker = _marker;
          }
  
      }
  
      // Tree Harvest script access
      public List<QM_Tree> managedTrees = new List<QM_Tree>();
  
      void Start()
      {
          // Scan for tree to "respawn" (remove cube, make available again) every 15 seconds
          // Adjust to your needs using a fast spawn here for demo
          InvokeRepeating("RespawnTree", 15, 15);
      }
  
  
      private void RespawnTree()
      {
  
          if (managedTrees.Count == 0)
              return;
  
          // Removing the demo cube and allowing tree to be used again
          for (int cnt = 0; cnt < managedTrees.Count; cnt++)
          {
              if (managedTrees[cnt].respawnTime < Time.time)
              {
                  Destroy(managedTrees[cnt].marker.gameObject);
                  managedTrees.RemoveAt(cnt);
                  return;
              }
  
          }
      }
  
  
      public void AddTerrainTree(string _terrainName, int _treeIDX, float _respawnTime, Transform _marker)
      {
  
          managedTrees.Add(new QM_Tree(_terrainName, _treeIDX, _respawnTime, _marker));
      }
  }





Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

114 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Destroy Terrain Trees And Their Colliders 0 Answers

tree billboard are just pixels with terrain billboard 0 Answers

Spawning Terrain Around The Player 0 Answers

Not able to place trees 0 Answers

Destroy Terrain Trees And They Collider 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges