I made a small thing about magnitude checks and Region3s
, I hope it helps!
About Magnitudes
For magnitude checks, you would need a collection of parts to check first for the NPC to be aware of. It’s useful if you already lessened that collection to something manageable. You can’t just use workspace:GetDescendants
to get every part in workspace and check their distance, because that would lag the game a whole lot. Unless you are checking a smaller group of parts, like players’ characters, you should not use this method.
If you find the difference of two Vectors and get the .Magnitude
of the result, you can essentially find the distance between the two points:
local dist = (Position1 - Position2).Magnitude
-- or...
local dist = (Position2 - Position1).Magnitude
Using this distance formula, you can figure out how far away objects are from a position, and factor that into your NPC’s decisions, like looking at a player or something like that:
if (NPC.Position - Player.Position).Magnitude < 20 then
MakeNPCLookAt(Player.Character)
elseif NoOtherPlayersFound() then
StopNPCLook()
end
NPC.Position
and Player.Position
would (obviously) be replaced by their respective humanoid root parts/heads/torsos
For this specific example, there is a better way of doing it:
local dist = Player:DistanceFromCharacter(NPC.Position)
if dist ~= 0 and dist < 20 then
MakeNPCLookAt(Player.Character)
elseif NoOtherPlayersFound() then
StopNPCLook()
end
About Region3s
Region3s
don’t loop through every single part in workspace, somehow, unlike magnitude checks would have to under normal circumstances. It is also a Roblox method, meaning it executes in C++, so it’s definitely faster than looping through every part in workspace
if you don’t have any way to lessen the pool of parts to search.
Region3s
are simple enough to use, they can be created using Region3.new
and a minimum/maximum bound Vector3
:
local r3 = Region3.new(minBound, maxBound)
You can use a formula like this to get a Region3
around your NPC:
local r3 = Region3.new(NPC.Position - offset, NPC.Position + offset)
Keep in mind that NPC.Position
isn’t a valid property (obviously), you have to use the humanoid root part’s position (or whatever limb you want really) instead.
The size of offset
could probably be based on the humanoid’s walk speed, but it can be larger if you need it to be:
local offset = Vector3.new(1,1,1) * Humanoid.WalkSpeed
The method Workspace:FindPartsInRegion3
takes three arguments, the Region3
to use, a part (and its descendants) it should ignore, and how many parts to search for before stopping:
local Parts = workspace:FindPartsInRegion3(r3, ignore, num)
-
r3
was pretty much already defined in the above blocks
-
ignore
will probably just be the NPC’s character
-
num
can be decided by you, the smaller it is, the more efficient it will be.
This method will return an array of parts that you can use like :GetTouchingParts
.
The more efficient cousins of FindPartsInRegion3
is: