CFrame.new(Vector3, Vector3) creates a CFrame whose position is point A and whose rotation is pointing from point A to point B. Point B is not a direction (as your script has it), it is a position.
Your code is pointing that CFrame from Shot’s position toward something really close to (0, 0, 0). The direction isn’t always the same, it’s simply directed toward the origin, go anywhere else and the direction of the coin will change.
The accepted answer “works” because it’s pointing from the coin’s position to a kinda random position. If you’re near the origin, the direction really will be kinda random. If you go 1000 studs away from the origin, it will start tossing the coin toward the “same direction every time” again because it’s still pointing toward a position, not in the direction you created.
Do this instead:
Ricochet.CFrame = CFrame.new(coinShot.Position, coinShot.Position + randomVector) * CFrame.new(0,0,-distance/2)
Now it’s located at coinShot.Position and pointing in the same direction as the random vector, regardless of where the coin is.
Point B is now an absolute position, not a relative direction.
local pos = coinShot.Position - randomVector * (distance / 2)
Ricochet.CFrame = CFrame.new(pos, pos + randomVector)
(I can’t be certain whether pos should have a -
randomVector*distance or a +
While you’re at it, use a uniformly random direction (source):
local a = 2*math.pi*math.random()
local x = 2*math.random() - 1
local r = math.sqrt(1 - x*x)
local y, z = r*math.cos(a), r*math.sin(a)
local randomVector = Vector3.new(x, y, z)
A LookVector is a unit vector, which is any vector whose length (
.Magnitude) is 1. It has little to do with radians or degrees, it’s just three otherwise uncorrelated numbers whose squares add up to 1.
For example, if you get the .Unit of the position of some random thing in workspace, then you get the direction pointing from (0, 0, 0) toward that position.
You should ask your maths teacher to explain this stuff to you.