Others here are right, while-loop requires some waiting, otherwise it exhausts all allowed execution time. However, don’t use wait(). It’s not OK to use it anymore, and here is the reason why (avoid delay() and spawn() in your work as well).
I just got tons of information about wait() function from @evaera’s article on eryn io. Visit her article to get tons of information instantly!
Jokes aside, I don’t know what you are checking magnitude for, but perhaps there is an alternative to constant magnitude calculations.
local RunService = game:GetService("RunService")
while true do
for i, v in pairs(interactions:GetChildren()) do
local magnitude = (humanoid.Position - v.Position).Magnitude
if magnitude <= 8 then
script.Parent.Text = v.Prompt
-- wait(1) ==> Not demanding, slower response.
RunService is much more consistent and reliable than wait(), while
having same run frequency (1/30). In the near future, you should
replace Heartbeat with its successor .PostSimulation:Wait().
RunService.Heartbeat:Wait() -- Very rapid.
How else could you check player’s presence?
- .Touched event
The following is pretty performance friendly. It help you detect colliding. Once the collision stops, .TouchEnded is activated. There are different ways to detect object touches. For example, you can check the name
if (hit.Name = "HumanoidRootPart) then end
Check for parent’s name:
-- *Suppose that Players service is already defined.*
if (Players:GetPlayerFromCharacter(hit.Parent) == "player's name here") then end
Of you can check for object’s class:
instance:IsA() --> check if instance is class or subclass of given class.
instance.ClassName --> read-only property, ignores inheritance
There are even more of various checks you can do. For instance, you can use :FindFirstChild(“name here”), :FindFirstChildWhichIsA(“”), or :FindFirstChildOfClass(“”). Former is similar, but ignores inheritance, so it’s more strict.
The following example has a little weakness. However, the fact that complete touching of all part’s surfaces is required can be a minor drawback, but expanding part’s size pretty much solves the problem for good. It’s worth to mention that .Touched event is not as reliable at high speeds (hundreeds of studs per second).
Detector should be anchored and have collisions disabled.
Other properties are up to your choice.
local box = workspace.Box -- your part
local is_inside = false
if (hit.Name == "HumanoidRootPart" and not is_inside) then
is_inside = true; print("INSIDE")
-- execute code here
if (hit.Parent:FindFirstChild("HumanoidRootPart") and is_inside) then
is_inside = false; print("OUTSIDE")
-- execute code here
Regions are excelent, but you should think carefully when using them. Overuse leads to performance drops (of course, we are talking about large regions). I don’t, however, think you need to use them in this case. Read more about region3 here.