- Home /
How to improve the Performance of Removing Trees during runtime?
Hi there,
do you see any way how to improve the performance of this method? The moment it reaches the data.treeInstances = _treeList.ToArray();
the game freezes for 1-3 seconds. And I don't want to imagine how long it will freeze on my team member's PCs...
Some explanaition:
there are around 7000 trees, created with help of the terrain tool
the trees that shall be removed were calculated in another method and added to the list of the area included the trees.
public static IEnumerator RemoveTrees() {
TerrainData data = Terrain.activeTerrain.terrainData; TreeInstance[] treeInstances = data.treeInstances; List<TreeInstance> treesForRemoval = new List<TreeInstance>(); foreach (BuildingArea area in _buildingAreas) { yield return new WaitForEndOfFrame(); if (area.IsBought == true) { if (area.HasTrees == true) { treesForRemoval.AddRange(area.treeRemovalList.ToArray()); area.HasTrees = false; } } } // remove trees _treeList.RemoveAll(x => treesForRemoval.Contains(x)); yield return new WaitForEndOfFrame(); // replace trees on terrain data.treeInstances = _treeList.ToArray(); yield return null; }
Answer by SchecterKing · Jul 09, 2013 at 07:08 PM
Isn't that what billboarding is for? I can't recall the name of the article on wiki that describes this, but try this: Divide your map into 4 sections using cubes with a transparent texture on them. Add a script to it and use the "OnTriggerEnter()" "OnTriggerExit()" functions in the unity API after selecting the cubes as triggers in the inspector panel. Continue to divide each cube inside itself by 4 sections. You can also use a memory profiling tool to determine where the cubes need to go based on memory usage of your map in those locations.
OnTriggerEnter: http://docs.unity3d.com/Documentation/ScriptReference/Collider.OnTriggerEnter.html OnTriggerExit: http://docs.unity3d.com/Documentation/ScriptReference/Collider.OnTriggerExit.html
That comment made me smile =]
I think there is some confusion here, so here's what I think the question is :
Imagine the terrain as a forest. Then someone comes along and chops a group of trees down to build a settlement. So the trees are removed from the terrain data. The problem I think is the above code is taking a long time to remove the tree instances from the terrain data.
$$anonymous$$y guess is the problem is arising from the loop that is rewriting the whole tree instance
_treeList.RemoveAll(x => treesForRemoval.Contains(x));
As a test, you could put a debug before every yield to see where it starts to lag.
I have no desire to downvote this answer, whoever upvoted has also misconstrued (unless I've got it wrong), but this is just to express this is an answer to totally a different question =]
measuring time didn't help me at all :(
time = Time.time; // debug
// actually replace trees
data.treeInstances = _treeList.ToArray();
Debug.Log("remove end " + (Time.time - time)); // debug
all the 4 loop results are around 0.29 seconds. The one with the _treeList.RemoveAll(x => treesForRemoval.Contains(x));
was 0.33 (at least console says so...) and the code section above is 0
Since I commented the section above out, and the lag still happened, I think you might be right. The reason for this lag is probably the RemoveAll thing. But do you have any suggestion how to speed it up?
Your answer
Follow this Question
Related Questions
Remove Trees during runtime 1 Answer
To what extent can the tree system be used instead of the details system 0 Answers
List Performance Question 2 Answers
Replacing terrain trees with prefabs 0 Answers
Tree Billboards 1 Answer