I’m working on a RTS Game and i want my Units to see each others… by searching the Forums and Google i found a way to determine seeing by Line of Sight by casting Rays.
Like this:
Here we cast a Ray from one Pivot to the another… and yes, there is an Obstacle in the way - so we cant see… Until here i don’t have any Question.
I want to ask you for an idea how to figure out a fast way to Calculate the yellow area.
I have Googled and found occlusion culling. If i do a occlusion culling for the Unit then i can determine which ones are “really unseen”, but i still don’t have the yellow area… maybe there is something else that exactly return this? And maybe without doing tons of Raycasts…
Thanks in advance…
I’m from Germany so maybe my English is under all pig, but that’s sausage i hope.
You could use a binary search type approach to limit the number of raycasts you need. Decide on a field of view for the tank’s eye, say it is 90 degrees.
Start at 0 degrees and cast a ray at increments of N degrees (say 15) all the way to 90 degrees (6 rays total if N=16). Take note of the pairs of angles where the raycast changes from a hit to not a hit then vice versa.
Then go back and cast two rays between those angles at N/3 degrees (5 degrees, or whatever precision you need) . Take the total set of 4 rays, the original 2 plus you 2 new ones, and set the point for your yellow area to be the midpoint between the two angles where the state changes.
You could adjust parameters to get better performance or better accuracy. For you illustrated example you would get good precision with a total of 10 rays. As tanks got farther apart you might have to adjust the precision, but you might call that a feature. Harder to see a tank peeking around a corner if it is far away!
edit - more ideas - if you kept track of each tanks left and right most points, instead of their centers, you could restrict the field of view within which you cast rays by quite a bit, then rather than searching across the whole field of view you only search between those two extremes. In the example that would cut the rays in half.
what exactly are you trying to calculate? the angles of your yellow triangle, the area on screen? I would most likely use the render bounds or mesh bounds of the obstacle and the target to get your two end points of your triangle
Render bounds will get you the end points regardless of occlusion right? But that would be a handy way to bound your search for the points where the object transitions from occlusion to visible.
If i understand right, then i have to brute-force-like raycast the FoV or at least between all Mesh bounds.
Imagine in an Space RTS Game where each unit have a FoV of 360° in each direction. I really don’t want 1000 of Units brute-force cast rays against and in between the bounding boxes. - That why i want to go away from this “Line of Sight”…
A Shader producing an black/white Texture, while Units will be white (lit) and other uninteresting Surfaces stay black.
I didn’t know much about Shaders yet, but as far as i know we can for example setup a bunch of vectors or transformation matrixes in the Shader that holds the “seen” points and then parse them with GetVector() in the Update loop…
This will lesser hackie than the Texture method and won’t me require to buy Unity Pro… AND this maybe is faster then even just casting one ray because the GPU will do. Evolution for AI.
Now the BIG ? … I have no plan how to Setup such a Shader…
It would be really nice if Somebody with experience could show me the direction…
Unity can handle a lot of raycasts so I don’t know that going into render textures etc is going to be any faster. Coupling this with limiting how many checks you do per frame and/or not checking every frame will increase your performance as well.
Thinking further along those lines - 1000s of units, many of your raycasts may take care up multiple units at once. So rather than using render bounds on each unit to set up a range of points to scan with raycasts, you could just do a 360 sweep at N degree increments using RayCastAll, then refine based on the hits you get.
I just write a little benchmark for Physics.Raycast. My Notebook (Intel Core i7-2670QM, GTX 570M) makes ~250.000 per second.
250000 / (8 Players * 500 Units) = 62,5 Raycasts per Unit per second. I think this is not very much for brute-force-seeking targets, remember that the precision will go down exponential with distance. And there is no other behavior in the calculation.
I don’t think that this numbers are very precise - but i think that a Shader can do this much faster with much greater precision…
Did you ignore RayCastAll from jackmott’s suggestion? it seems like you did. I think you should use this suggestion, reduce the cone to the unit FOV (if necessary) then do say, 25 units a frame. This would be easily realtime in behaviour. It is not as if each unit needs to respond within 16 milliseconds.
A simple bucket list would further reduce processing as well… brute forcing it seems like the wrong approach.
for (deg =0; deg < 360; deg += 10)
{
hits[] = RayCastAll(my position, deg,distance);
foreach hit in hits
{
if hit.collider.gameobject == unit {
unit.HitPointList.Add(hit.point);
unitsHitList.Add(hit.collider.gameobject)
}
}
}
foreach unit in unitsHitList()
{
//cast a few more rays near the hit points for each unit to refine
}
This may still not work if units are too far away, but still need to be evaluated.
Since i’m tired i first want to say thanks to all of u for patience, helping me, spending your time and bio-kinetic energy.
This hint with the RenderTexture makes me so much willed to solve this with a Shader, that tomorrow i want to continue in this direction and i hope we can continue the exchange on that.
So please don’t be sad, but raycasting seems to be the inefficient way in my FoV.
Well, 360/10 is 36 raycasts, if you did every 1 degree that is 360 raycasts. He seems to want to check over 1000 units, checking each individually is 1000 raycasts. If there is a limited sight range then yeah this becomes simpler.
36 raycasts with less accuracy or 1 overlap sphere that gets everything? I’d go with OverlapSphere
And no - 1000 units does not equal 1000 raycasts if you do it correctly and even so - 1000 raycasts a frame shouldn’t be an issue.