part.Velocity = (bullet.CFrame.lookVector + Vector3.new(random(-offset, offset), random(-offset, offset), random(-offset, offset)).Unit * speed
or wat is the proper way to do this?
This is mostly a proper way to do this. For many things it is good enough; it does not bias depending on distance and is fairly unbiased in all directions.
If we are being extremely rigorous, this isn't quite good enough. Generating in this way generates the results in a cube, which will cause the result to be biased slightly to (+-X,+-Y,+-Z) and away from the axis. Ideally, we would generate uniformly from the unit sphere, instead.
I am unsure whether or not it is better to generate the points uniformly from the surface of the sphere, or the volume of the sphere. Both have similar properties, but from the volume of there sphere the expected inaccuracy would be ~ half of from the surface.
From Wolfram Math World, we have the following way to generate a point randomly and uniformly on the surface of a sphere:
function randomFromSphere() local u,v = math.random(),math.random(); local theta = 2 * math.pi * u; -- Azimuthal angle local phi = math.acos(2 * v - 1); -- Polar angle local radius = math.sin(phi); local up = math.cos(phi); local ax = math.cos(theta); local ay = math.sin(theta); return Vector3.new(ax * radius, up , ay * radius); end
We would then instead use
velocity = lookVector + randomFromSphere(); -- or velocity = lookVector + randomFromSphere() * math.random();
I am unsure which is better.