I've been trying this for a few days, but seems I'm unable to undestand some concepts or I'm missing something on terrain trees, so I need the help from my fellow forum colleagues.
Let's say I have a terrain, and in this terrain, I generated several trees. I activate the Tree Collider option in the terrain, and added a capsule collider to the prefab. When putting a Character Controller in my camera, it does collide with the tree and I can't walk through the tree.
Now I want to click on my screen and select a tree, so I thought, seems a good use for raycast, then I did it, but all I get is a reference to the Terrain object. I read somewhere that Unity bakes all my tree colliders with the Terrain collider, and that's why I'm getting only references to the terrain. Then I thought, okay, I need to check the position where the ray crossed the terrain, and verify if there's a tree by serching the TreeInstances object. The problem is, doing that is VERY imprecise. If I just compare with the position in the ray, I must click too exactly and this makes me click like hell to select a tree, and if I put some x and z tolerance, I can end selecting several trees at once, and that's not desired.
Is there a way I can achieve that (clicking and getting the tree I tried to click) correctly? Thanks in advance.
asked Sep 09 '11 at 01:26 PM
Yikes this is really going to throw a hitch into my game. I was hoping to chop trees by adding a rigidbody to make them fall. Now it seems there will not be a way to do this with the current system without adding trees individually. Hmm..
answered Dec 10 '12 at 12:58 AM
I've only peeked at these. Do you need a specific tree? Can you send your unit to an area and have the unit just find the closest tree? Or do you really need to have the units chop specific trees down?
I'm thinking that your choice of picking a ray on the terrain and iterating position would be good. Is there an easy way for you to make your precision a little more "fuzzy"?
The other option that occurred to me was at Start(), iterate thru all of the trees and add a collider to each tree location, probably with some viable offset to put the collider where you need it to be. I only hesitate in suggesting this as there could be thousands of trees in your game, and this could be a performance problem. I also am unclear how best to deal with getting a collider to relate to a specific tree without an instance of a script on each one - again unclear how this would effect performance. eg: Iterate thru trees. Add GameObject with collider and script. Set value on script to point to this tree and reference collisions from this collider.
answered Sep 09 '11 at 10:16 PM
Little Angel ♦♦
Well, so far I couldn't get it to select one tree, and placing a collider for each tree by script was indeed a performance problem, so I can't follow that route. I'll plan using for my game something like Rise of Nations wood gathering system, although this will take away a bit of the realism I wanted for it.
I'll leave the question open in case anyone got a tip or a full solution to that.
answered Sep 11 '11 at 03:36 AM
I've been experimenting with the same challenge. Here are some thoughts.
I want to be able to detect mouse clicks on trees, bushes, heck maybe even grass. Since Unity considers all trees and such as part of the terrain, the first trick is to decide if we have selected the terrain or not.
If we get the collision point from a raycast, axe strike, whatever, if we can determine the terrain height at that point, we can know if we hit the terrain or not. If the hit point is a meter above the ground...well, we must not have hit the ground, so it's a tree or something.
Once we do that...it means searching through all trees and such to see what we hit, by finding the closest tree. I haven't tested this yet, so I don't know what kind of performance hit this will mean. The demo others have mentioned where you can blow up trees in your area seems to run VERY fast, but I don't know how many trees he has. I have a lot. But even so...it's a start. If it is a big performance problem, you could split up the trees in the map into sectors, and only compare against trees in your sector.
Just some thoughts, maybe useful, maybe not :)
[Edit] I was indeed able to do this, by casting a ray. If I hit "terrain" (which may be a tree, dirt, a detail object, grass, etc), I then used Terrain.SampleHeight to get the actual ground height beneath the ray hit location. If the ray hit height was above the ground height...I knew I hit a tree or detail object instead of the ground. At that point, I cycled through all TreeInstances and found the closest one, and remove it.
The big problem (and final hurdle that I know of) is this: It doesn't remove the tree collider!! So even though the tree is gone, the collider still exists. I don't know how to remove the collider also. So, at this point I'm going to just remove all colliders from my trees, and try to dynamically place colliders only on the trees near my character. Wish me luck, and hope that UT will someday add more support for the terrain API.
I think I'll eventually have some code that launches when the game starts, and looks at all trees and partitions them into regions...and check only the trees near my character, should speed things up. Especially if you have a lot of trees, in one scene I had about 50,000 trees and the sort algorithm took a tenth of a second...a bit much.