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.