Best way to detect closeness for popup

In a lot of games when you approach a certain NPC, object, etc… dialog pops up and will say something like “Press ‘f’ to interact”. What is the most EFFICIENT way to determine when to fire these pop-ups. Would it be magnitude, touch events etc? Thanks just curious

Touched events can tend to be very unreliable,

Magnitude as well as DistanceFromCharacter are both good.

Somehow accidentally deleted my post.

4 Likes

I could be completely wrong here, due to not testing performace…

But making a region around the player and then cycling through the table that it returns will most likely be way worse in the performance as well as delay depending on how many objects are around the user.

Forgot to add that you could use a whitelist.

So for instance you check a region3 maybe twice a second, then scan a whitelist of objects that identify as NPCs. If you have a very large game with lots of NPCs, then you could divide them into “sectors”.

There are definitely other ways to handle this however I’ve found it be useful.

This is (for a non-enormous amount of points) way more performance intensive and complex (although probably not noticeable, still) than i.e. looping over all points-of-interest 3-4 times every second and doing the magnitude check. Keep it simple, it’s often the best solution.

EDIT: assuming you don’t have an enormous amount of points-of-interest (i.e. >10k), but since you are talking about NPCs/objects this is probably not the case.

4 Likes

Using a Region3 will still require something to iterate over everything in another region. Yes, Roblox has worked to make these efficient, likely through uses of things like chunking.

Unless you have thousands of NPCs, you can very efficiently just check the magnitudes between the NPC and the player every frame. If you do have a large number of NPCs, then you can likely afford to just chunk them up.

Another way, if you really do have enough NPCs, is to just group NPCs into regions and then every frame just check what region the player is in and then get the distances for each NPC in the same region and neighboring regions.

2 Likes

I agree, checking an array of say 1,000 NPCs a few times a second using a region3 isn’t going to yield good results if it’s done improperly. I was thinking more along the lines of using “sectors” to determine the location of the player.

In the past I did something like this in the past but it only worked in a performant manner because of how I used the system, so thinking again, probably not a good idea for what OP is looking for.

So, at some point you will want to check the direct distance between the player and the NPC but there are optimizations you can make before then.

Firstly, for any NPCs which do not move, you can split them into regions. The regions are essentially cubes of N×N×N studs. When a player enters a region you can perform a distance check on the region they are in and any neighboring regions.

For moving NPCs, you can assign them to these zones as they move around the map, or if they only stay in one zone while moving they can be treated the same way as a static NPC.

You also only need to check the distance between one part of the character and one part of the NPC.

4 Likes

Perhaps a good implementation of this would be having separate regions like you suggested, and simply checking the if the player is within a region3 maybe once a second. (or checking magnitude)

From there you could magnitude check every NPC within the region every so often, depending on how many NPCs are within that region.

Couldn’t I just check the bounds of my character’s position to the bounds of the region a lot faster without having to use a region3.

1 Like

We need to consider the efficiency of this strategy, as constantly checking for region3 can be really stressful and inefficient performance wise.

1 Like

Stop. With. These. Region3. Implementations.
They’re way too much for this.

Just check if the player is in the region by quickly checking that their X,Y,Z coordinates are in the ranges of the region.
Then check the distance between the player and all the NPCs in that region as well as neighboring regions.
You can easily do this once every five frames with no cost so long as you have a good balance of NPCs per region and number of regions.
Your regions don’t even have to be equally sized.

2 Likes

Maybe, however there are other variables that tie into how this affects performance.

If I am understanding you right, what you suggested is similar to what I was suggesting but with a better implementation?

  1. Compare the coordinates of the player to all the sectors / regions (NOT a region3, region as in the dictionary definition of a region)
  2. When the player is “within” or “close to” one or multiple regions, check the magnitude between each NPC in that region and the player?
  3. If the player is within x distance to one of the NPCs, trigger it’s popup dialog?

I would cast a region3 (size of 10x10x10 or something) around the player with a whitelist of only the npcs, then sort the list by magnitude then just take the first value in the sorted list.
I would only cast it once every 120-60 frames though since I don’t see the point of extreem accuracy.

But that’s what I would do, no idea if it is the fastest or not.

Yes. Except you kept mentioning this idea of Region3s, which is a dangerous idea that I would definitely not suggest adding for this sort of system.

If you do have moving NPCs, they are unlikely to move through two regions in any reasonable amount of time. You can have another loop that is checking what region all moving NPCs are in once every half second or so.

1 Like

So @BigThunderBoy it seems like the general consensus is that unless you have a high amount of NPCs you can just use a loop and magnitude check between the player and the NPCs a couple times a second. If you have only a few NPCs this will be fine and you can ignore the rest of what I’m saying.

Going along the lines of what @ProbableAI said and based on the general consensus of what other people in this thread are saying:

(And if anyone can spot anything wrong with what I am suggesting or wants to add to it go ahead!)

How to handle lots of NPCs using sectors

The above is generally not a good way to design a game if you intend to keep adding NPCs to it, especially if you have a high amount of NPCs you would be better off designing a sector based system.

Create an array or table of sectors. A sector could be defined as a 2D square or a 3D cuboid “region” of NPCs.

For example we can take the coordinates A = 0,0,0 and B = 20, 20, 20

This is a pretty small sector but I’m choosing it for the sake of example.

In the picture below, the blue part is corner A at coordinates 0,0,0 and the green part is corner B at coordinates 0,0,0. The red part in the middle is a part that shows what space the sector / region would occupy

Image Example 1

Now as I said before this is an example, I am not advising you to use region3s or make parts and check collisions as those would be inefficient options.

Let’s pretend that you place an NPC at coordinates 10,0,10 as depicted in the image above. Let’s call him Bob. For this example, Bob won’t be able to walk around.

Anyway, Bob’s coordinates would put him within the above sector. You could either manually assign NPCs to their sectors, or write code that could do a distance check every few seconds to detect what sector the NPC is in.

Anyway, so let’s say you have an array of 15 sectors, of varying sizes and positions, with varying (but somewhat even) amounts of NPCs inside of them. For this example lets say you have 1,000 NPCs (I know, a bit ridiculous, but it’s an example).

Since there are 1k NPCs and only 15 sectors, it’s MUCH more efficient to check the distance between each sector first.

EXAMPLE:

  1. Every 0.5 seconds (give or take depending on how many sectors / npcs there are), find the players position and compare it to the positions and sizes of each sector.
  2. If it has been calculated that the player is within one or more sectors, return a list of each NPC within the listed sector(s).
  3. Check the distance between each NPC returned and the player using magnitude.
  4. If the closest NPC is within the set distance to trigger it’s popup dialog (ie within 10 studs), then assign it to a variable called “nearest_NPC”
  5. When F is pressed, check if the variable “nearest_NPC” is empty or not, if it’s not empty then trigger the popup dialog for that NPC.

ALTERNATE METHOD:

You could also only run this function only when the F key is pressed. This has it’s drawbacks and you would also need to install a delay and switch so that spamming the F key doesn’t run the function a thousand times and crash your game.


Let’s look at the pros and cons of both of these methods:

Pros:

  • Efficient
  • Scales well

Cons:

  • Somewhat complicated
  • If the process of assigning NPCs to regions is not automated, manually assigning will be somewhat time consuming

I hope this helps!

2 Likes