Iād recommend using Player:DistanceFromCharacter for a few reasons:
Who knows how long the HumanoidRootPart will be around? Not long ago, it didnāt exist. Using DistanceFromCharacter allows Roblox to adjust how the distance is found while still achieving the same end goal.
DistanceFromCharacter require less indexing in lua, and allows for shortcuts and optimizations on the C++ side, since C++ has access to information Lua doesnāt and is much, much faster.
It looks cleaner and is even labeled with its purpose
However it should be noted that when it comes to performance, data is key. Weāll never know until we test it!
If you end up with performance issues due to how much it is running in a loop, then Iād recommend not looping at all! Iād have to know the use case to suggest an alternative, but usually loops dealing with distances in Lua can be avoided by things like bounding sphere hit boxes being welded onto players or other parts.
Itās not intensive at all, but wait() and wait(n) are inconsistent in their timing and will take longer than you might expect. I would recommend using a RunService.Heartbeat connection, especially for something as non-intensive as this.
Worth mentioning that every time you access Mouse.Hit, the engine actually performs a raycast behind the scenes to determine what part is being hit ā this is the āintensiveā part of that line of code. Then computing the distance between that and the HRPās position is extremely cheap in comparison to that raycast.
But like others said, as you only run this code once per frame (or even fewer times using wait), this single raycast per frame wonāt cause any issues anyway.
Player:DistanceFromCharacter is my go-to, however if you like using .Magnitude, Iād recommend using player.Character.PrimaryPart instead of assuming the player has a HumanoidRootPart. Happy Birthday!
Going to leave this here for completeness of the question for future.
I heard using magnitude is slow due to the square root. Calling it every ā.01ā seconds should be okay though.
If you ever have to call it a lot more to do some kind of distance check, I would recommend using the Pythagorean theorem without squaring. General idea:
local v = (player.Character.HumanoidRootPart.Position - Mouse.Hit.p)
local distanceSquared = v.x^2 + v.y^2 + v.z^2
if distanceSquared < 25 then -- 25 would actually be 5 studs (5^2 = 25)
-- do stuff
local dis = math.sqrt(distanceSquared) -- use this to draw lazerbeam or whatever
end
You donāt need this unless you are doing a large amount of distance checks in a short amount of time.
As a fair warning, unless it has been changed since Iāve last used it, DistanceFromCharacter will return 0 if the character is destroyed/missing/not spawned yet. (This could trigger some false positives if you were not expecting this case) Iāve historically avoided this function because of this property. (Also this call has to be sent through the C++/Lua bridge which slows it down a bit)
On the other hand, magnitude is fairly inexpensive if used a single time per frame. You could always benchmark this (typically done by calling your function with magnitude a few thousand times in a frame and measuring the time elapsed before and after every operation) on different machines/devices if you want to know the factor of the cost for your specfic usecase.
You are comparing apples to oranges: Mouse.Hit is a CFrame; not a Vector3
No idea how intense .Magnitude is, but you may wait(.1), or maybe wait(.4): No Avatar moves that fast, and no one clicks that much.
Also, I will answer your next post before you posts it:
Why is Distance never less than 3 studs, or if using DistanceFromCharacter, why is Distance never less than 5 studs?
Most often people say, āWhy is .magnitude is so inaccurateā?
They forget that the Torso is 3 studs off the ground; yet they are measuring from the center of the Torso to the spot Clicked on the BasePlate. (DistanceFromCharacter measures from the center of the Head)
.
If you are trying to find the distance between the character, and a spot on the āBasePlateā (You have not stated what u r trying to do), you are going to have to use .magnitude. In almost all . magnitude calculations involving an Avatar, you are going to have to strip the Y value from the calculation.
You might want this:
while wait(.1) do
local Root = player.Character.HumanoidRootPart.Position
local Hit = Mouse.Hit.p
local distance = (Vector3.new(Root.x, 0, Root.z) - Vector3.new(Hit.x, 0, Hit.z)).magnitude
if distance < 1 then
print("We are close enough", distance)
end
end
Not tested.
If you want to use DistanceFromCharacter, replace the Y Value with the Heads
print(player:DistanceFromCharacter(Vector3.new(Hit.x, [The Heads Y Value], Hit.z)))
PrimaryPart can be nil too. PrimaryPart is a BasePart reference. Both can be assumed to exist and both can return nil, thereās no difference except for one being indexed by a property.
Thatās repeating the point I was making. Both need to be checked for existence because both can yield a nil, in which attempting to operate on a nil value will throw an error.
As the solved reply stated, DistanceFromCharacter has the work pushed to the engine backend and only a few internal changes are necessary - itāll always work as intended aside from that.