Unity3D: How to spot nearby triggers around my players?

Started by
4 comments, last by babaliaris 3 years, 4 months ago

From the docs, I believe this is not possible using a trigger.

My players need somehow (every frame) to collect the first 10 nearest waypoints around them.

These waypoints should be invisible and not block (collide) other moving objects. So they must either have a trigger collider or no collider at all.

My first thought was to make a sphere trigger around the player and any waypoint that enters that trigger will be recorded. But this is not going to work since the waypoints are also triggers.

My GameManager script has a list of all the waypoints, but looping them every frame for each player (4 players in total) in order to get the 10 nearest to the player can be very inefficient!

So how can I solve this problem?

Thanks!


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

Advertisement

You neither need any of them because as it sounds, your waypoints are just data, so treat them as if they were data. For a visual representation it is totally fine to use Gizmos.

What you are looking for is a data structure that helps locating spots in an area. Those data structures are usually trees like a Quad- or R-Tree. Both have benefits over the other, while Quad-Tree is faster for static areas, R-Tree is faster when areas are changing frequently because it only covers what is really needed.

Those Trees allow to perform a query into certain area and get any of the n nearest objects in certain radius.

However, you shouldn't need to query every frame as every second/third frame might also still be precise enougth for whatever you are doing to work properly

Well, I only know about binary, B, and Β+ trees, never heard of a Quad or an R tree.

Anyway, I thought that triggers could not collide with other triggers but I was wrong. So I created a Sphere trigger around the player, and every time a waypoint enters the trigger I add it to a list. Every time a waypoint Exit's the trigger, I remove it from the list.

So I successfully maintain a list with all the waypoints that are nearby the player.


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

Assuming you're using a trigger collider, you can use the spatial trees built into Unity to reduce your search to begin with. Physics.OverlapSphere can query all your nearby trigger colliders efficiently, even better if you can filter for with a layer mask. Assuming there isn't too much motion every frame or change to the objects you could keep that collection around for a while. So not knowing the details of your system maybe the OverlapSphere() query returns the nearest 20 or 30 items that are nearby, then you only need to search those for the nearest 10 rather than searching the entire world. You could also dynamically change the size of your sphere based on the collection size returned, if you don't find enough set your code to expand the search radius in the next pass, if you find too many set it to reduce the search radius. This way you could perhaps be constantly growing/shrinking your radius to maintain the nearest 12 or 15 or 30 or whatever makes sense for your situation.

I'd question if you really do need this updated every frame. It seems like you could put this in a rolling system updating every few frames, or for multiple players do one player's test every frame.

I don't search every waypoint there is in the scene and check if it's nearby!!!

As I said I use a Sphere trigger collider and anything that enters I collect it. I think this is really good for performance!

I don't need to know how many waypoints exist in the word neither needs to search each one of them in a data structure.


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

This topic is closed to new replies.

Advertisement