- Home /
Remove a known TreeInstance at runtime.
So, I try to implement a "tree cutting"-method in my game. I do this by selecting an area and creating a new instance of a class "Work area". The work area-class contains a list of all the treeinstances in that area. The problem is I cant find a way to remove trees without editing the whole terrainData.Treeinstances-array.
List<TreeInstance> newTrees = Terrain.activeTerrain.terrainData.treeInstances.ToList();
newTrees.RemoveAll(x => x.position == currTree.position);
Terrain.activeTerrain.terrainData.treeInstances = newTrees.ToArray();
Having about 1300 trees this bit of code creates about 150KB of GC allocation. 54.5KB for get_terrainInstances(). 54.5KB for ToList(). 54.4KB for ToArray() (Values from deep profiling). There must be a way to remove a tree I already have the reference to in a better way. I don't have the index, just the reference to the instance.
Splitting up my terrain in smaller pieces is not something I rather do since I would have to change the majority of my code because of it (map generation, pathfinding, terrain editing, etc).
I've found similar problems on google, but there they (mostly) want a solution for an unknown treeinstance (ex. the tree closest to a gameobject) which is not a part of my problem.
EDIT: I tried to simply move the tree, to see if I could hide it away. but currTree.position = new Vector3(0,0,0) didn't do anything or atleast didnt appear to do anything since the tree model was still in the same position.
To clarify, you have a list of 1300 trees, and you want to remove a single tree (say tree 482 or something) and then have a list of 1299 trees?
Yes, exactly :) And I have tree 482 refered to in a variable (currTree refers to a TreeInstance). But I do not know the index of said tree. So I can't say "RemoveAt()" (which is why I use a lambda expression). The real problem when editing treeinstances is that I have to copy a list twice (ToList() and ToArray()) which allocates a lot of memory. So I know exactly which treeinstance I want to remove, but I still have to iterate over the whole list with a lambda expression.
Would simply using Remove() rather than RemoveAt() work?