x


Picking Trees with Mouse

Hello Everyone,

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.

more ▼

asked Sep 09 '11 at 01:26 PM

zharramadar gravatar image

zharramadar
230 6 6 16

zharramadar:

It may help if you tell us "why" you are doing this.

Is this in edit time? Or at run time? And why do you need to find out which tree you've selected?

Sep 09 '11 at 01:29 PM Little Angel ♦♦

I am doing this for a RTS game I'm doing. I want to populate the world with trees, and I want to be able to select a particular tree and send a troop to it so it can chop it down and start gathering wood. When clicking a tree with a gatherer selected, it should go to the tree and chop it down (which will remove the treeinstance and place a tree mesh in the place so it can fall down). For that reason, I need to pick one and just one tree. And it is at runtime.

Sep 09 '11 at 02:11 PM zharramadar

Oh, btw, I found a demo from Tom's (which later made the Tom Terrain Tools) where you walk and instance explosions, and then trees fall down, and he's using kinda of what I did so far, but it doesn't count for accuracy, as he's destroying an entire area, and I can do it so far for an area, but I need to pinpoint trees).

Sep 09 '11 at 05:43 PM zharramadar
(comments are locked)
10|3000 characters needed characters left

5 answers: sort voted first

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..

more ▼

answered Dec 10 '12 at 12:58 AM

madmike6537 gravatar image

madmike6537
199 1 8 30

(comments are locked)
10|3000 characters needed characters left

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.

more ▼

answered Sep 09 '11 at 10:16 PM

Little Angel gravatar image

Little Angel ♦♦
433 2 4 11

Or not use the terrain engine to place your trees... but then I'd suppose you'd lost the LOD system, and other terrain optimizations...

What is interesting to note is that (iirc) that these trees don't literally exist in the same way as other objects, do they? They are in game representations of locations on a splat map, no?

Sep 09 '11 at 11:14 PM Little Angel ♦♦

I'll try here with putting the terrain colliders. I'm using P|Terrain here so I may have tons of trees in the terrains, and maybe hurt some performance, but I'll check it and let you know. Not using the terrain engine to place the trees would be not feasible due to the amount of trees involved in the process. I'll play a bit more with the ray and tree position to see if I can get better results as well. I'll keep you posted, and thanks =D

Sep 09 '11 at 11:19 PM zharramadar

What does occur to me is that you might be able to write an editor script that places trees at random around a mouse click and sets them into the terrain. This might be a way to go. Then you wouldn't need to place the trees by hand. You could simulate your own tree brush...

Sep 09 '11 at 11:29 PM Little Angel ♦♦

My trees are already generated and populated into the terrains, it comes from a tree placement map generated in World Machine 2 and imported into Unity with the mass terrain importer tool from P|Terrain extension. I need to do exactly the opposite, I need to select and erase trees, and not in an area, but EXACTLY on a tree. I messed up around with the click tolerance in my script, but can't make it nice. I'll try now with creating colliders when the terrain is loaded.

Sep 10 '11 at 03:39 AM zharramadar
(comments are locked)
10|3000 characters needed characters left

hey, try this. Physics.SphereCastAll() to return the array of RaycastHit. and then still need to scan the treeInstances[], then get what tree you collid with. I think it can work.

more ▼

answered Dec 11 '11 at 06:22 PM

oxinhome gravatar image

oxinhome
1

(comments are locked)
10|3000 characters needed characters left

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.

more ▼

answered Sep 11 '11 at 03:36 AM

zharramadar gravatar image

zharramadar
230 6 6 16

Out of curiosity: was the performance hit in the set up phase, or when selecting a tree?

Sep 11 '11 at 08:26 AM Little Angel ♦♦

In the set up phase, and by using the paged terrain solution I'm using, having it there anytime a terrain is being displayed can be bad.

Sep 12 '11 at 01:39 AM zharramadar
(comments are locked)
10|3000 characters needed characters left

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.

more ▼

answered Oct 23 '11 at 10:53 PM

jc_lvngstn gravatar image

jc_lvngstn
453 24 29 40

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

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

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x1685
x1468
x983
x228
x225

asked: Sep 09 '11 at 01:26 PM

Seen: 1954 times

Last Updated: Dec 10 '12 at 12:58 AM