I’ve made a hitscan gun using rays. It all works fine I really just need help adjusting the following code to add some random spread to the bullets:
local function getWorldMousePosition()
local mouseLocation = UIS:GetMouseLocation()
local screenToWorldRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local directionVector = screenToWorldRay.Direction * MAX_MOUSE_DISTANCE
result = workspace:Raycast(screenToWorldRay.Origin, directionVector, raycastParams)
return result
end
I just want to add a few degrees of randomness to the ray direction, but I’m not sure how. I know I just need to adjust the directionVector, but any way I try to change it breaks my script so I’m asking for help here. Also I was able to get some spread by adding a random vector 3 to the directionVector but the spread was in a square which I think makes it seem wrong and all around I think that was a bad method
What do you mean by ‘normalize it after you add it’
I multiplied it by the previous magnitude, but I’m not sure what that part means. I’m not ultra great at working with rays yet and still don’t fully understand them sorry.
local function getWorldMousePosition()
local mouseLocation = UIS:GetMouseLocation()
local screenToWorldRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local directionVector = screenToWorldRay.Direction * MAX_MOUSE_DISTANCE
local dirMag = directionVector.Magnitude
local randomSpread = Vector3.new(math.random(-10,10),math.random(-10,10),math.random(-10,10))
result = workspace:Raycast(screenToWorldRay.Origin, (directionVector + randomSpread)*dirMag, raycastParams)
return result
end
------The function you gave me from the other post
-- axis: center line of cone
-- angle: angle from center to edge of cone
-- returns: a random unit vector inside the cone, evenly distributed along the partial surface of a unit sphere.
local function RandomCone(axis: Vector3, angle: number)
local cosAngle = math.cos(angle)
local z = 1 - math.random()*(1 - cosAngle)
local phi = math.random()*math.pi*2
local r = math.sqrt(1 - z*z)
local x = r * math.cos(phi)
local y = r * math.sin(phi)
local vec = Vector3.new(x, y, z)
if axis.Z > 0.9999 then
return vec
elseif axis.Z < -0.9999 then
return -vec
end
local orth = Vector3.zAxis:Cross(axis)
local rot = math.acos(axis:Dot(Vector3.zAxis))
return CFrame.fromAxisAngle(orth, rot) * vec
end
--my updated function
local function getWorldMousePosition()
local mouseLocation = UIS:GetMouseLocation()
local screenToWorldRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local directionVector = screenToWorldRay.Direction * MAX_MOUSE_DISTANCE
local dirMag = directionVector.Magnitude
local newCF = CFrame.lookAt(screenToWorldRay.Direction,directionVector).LookVector
local cone = RandomCone(newCF, .015)
result = workspace:Raycast(screenToWorldRay.Origin, cone.Unit*dirMag, raycastParams)
return result
end
Implementing the function from the other code took a lot of messing with for me because I had no idea what I was doing but this updated function seems to do exactly what I wanted, so I will be considering this solved, though I still don’t know if I’m doing it as effeciently as possible thanks. I’m just sharing so someone may find it useful in the future.
local function getWorldMousePosition()
local mouseLocation = UIS:GetMouseLocation()
local ray = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local cone = RandomCone(ray.Direction, .015)
return workspace:Raycast(ray.Origin, cone * MAX_MOUSE_DISTANCE, raycastParams)
end