Ay boys!
I’ve noticed several posts where people are aiming to find the correct formula for creating a distance UI/Bar. For those unfamiliar, here’s an example of what a distance UI might look like:
Understanding the Problem
Before delving into the solution, let’s understand the problem at hand. We have three points:
- The Start Point
- The End Point
- The Moving Point (in this case being the humanoid root part)
We aim to determine the relative position of The Moving Point in relation to a line segment defined by the Start Point and the End Point. The goal is to express this relationship as a percentage, ranging from 0 to 1, based on the Moving Point’s position between the Start Point and the End Point.
The Common Misconception
A commonly encountered formula involves taking the distance between the Moving Point and the Start Point or the Moving Point and the End Point, then dividing it by the total distance from the Start Point to the End Point.
local function getStartOffset(startPos: Vector3, endPos: Vector3, rootPos: Vector3)
local rootDistanceFromStart = (endPos - rootPos).Magnitude
local totalDistance = (endPos - startPos).Magnitude
return math.clamp(rootDistanceFromStart / totalDistance, 0, 1)
end
Why This Is Incorrect
The flaw in this formula lies in its interpretation. If you move away from the Start Point by a distance equal to the total distance, it incorrectly yields a value of 1, implying you covered the distance from the Start Point to the End Point. However, you might just be moving away from the Start Point but not necessarily progressing towards the End Point,
In other words, if you’re just moving away from the Start Point a distance equal to the total distance, it will return 1 even when you’re not even close to the end point.
The Correct Formula
The correct formula involves taking the dot product of the vector from the Start Point to the Moving Point and the vector from the Start Point to the End Point. This result is then divided by the total distance squared.
local function getStartOffset(startPos: Vector3, endPos: Vector3, rootPos: Vector3)
local vFromStartToRoot = (rootPos - startPos)
local vFromStartToEnd = (endPos - startPos)
local dotProduct = vFromStartToRoot:Dot(vFromStartToEnd)
local startOffset = dotProduct / vFromStartToEnd.Magnitude^2
return math.clamp(startOffset, 0, 1)
end
This Lua function efficiently computes the percentage and ensures it remains within the 0 to 1 range. You can apply the returned value as a Position X Scale component of the player thumbnail image label to move it horizontally along the UI Bar.