So I have a script that, when I click, a part moves from it's position to the mouse.Hit.p position, but I also want it to be limited to a maximum distance, how would I recalculate the target position to a new point with the maximum distance in the same direction.
I recreated my situation below, copy and paste it in a new project. Put it in a LocalScript in StarterPack.
01 | local m = game.Players.LocalPlayer:GetMouse() |
02 | local p = Instance.new( "Part" , workspace) |
03 | local v = Instance.new( "BodyVelocity" , p) |
04 | local c |
05 | p.Anchored = true |
06 | local point |
07 | wait() |
08 |
09 | function getDir(vec) |
10 | local lenSquared = vec.magnitude^ 2 |
11 | local invSqrt = 1 / math.sqrt(lenSquared) |
12 | return Vector 3. new(vec.x * invSqrt, vec.y * invSqrt, vec.z * invSqrt) |
13 | end |
14 |
15 | function ShowPointer(target) |
If anything is unclear, please leave a comment.
Any vector is a distance (a number) in a particular direction (a vector).
Since a scalar (number) multiplied by a direction vector is another vector (scaled by the scalar), a vector indicating direction is usually defined as length 1, so that dir * len
has length len
.
A vector of length 1 is called a unit vector. ROBLOX gives us a function to get the unit vector of any given vector through the .unit
property.
1 | displacement = target - position |
2 | -- The vector going from where we are (position) |
3 | -- to where we are going [toward] (target) |
4 |
5 | direction = displacement.unit |
6 | distance = displacement.magnitude |
We can get displacement
back by just multiplying direction
and distance
. If we want to make distance
at most maxDist
, though, we can limit it, for example, by using math.min
:
1 | distance = math.min( distance, maxDist ) |
2 | -- `distance` is now the smaller of `distance` and `maxDist` |
And to get the new target point at most maxDist
away, we just multiply:
1 | newTarget = direction * distance |
One warning: If position
and target
are the same, the unit vector is undefined and may cause problems if you forget about that.
A simple check before doing too much with it is to make sure distance
is at least, say, 0.001
.