I’ve already got a functioning automatic gun. I now just want it to have a bit of a random spread. I did find a similar thread with a very similar question but the solution wasn’t really what I was looking for. I want the spread to be like a cone shape and change depending on how close/far you are from whatever you’re shooting.
This is the current code (using the solution I found on another thread).
local function RayCast(Position, Direction, MaxDistance, IgnoreList)
local spreadAngle = 1
ray = Ray.new(Position, (Direction.unit * MaxDistance), IgnoreList)
local spreadRay = Ray.new(ray.Origin, CFrame.Angles(math.rad(math.random(-spreadAngle, spreadAngle)), math.rad(math.random(-spreadAngle, spreadAngle)), math.rad(math.random(-spreadAngle, spreadAngle))) * ray.Direction)
return game.Workspace:FindPartOnRayWithIgnoreList(spreadRay, IgnoreList)
end
This code as is does work, but like I said before I don’t like the result:
As you can see: the bullets do spread but there’s only 9 positions that slowly spread apart as you’re further away, and it’s in a square. Overall this is better than nothing, but I’m looking for something better.
The reason why the spread angle forms a box is because of the way math.random works with -1 and 1: you’ll only ever get -1, 0, or 1, and never any float values.
In your sample, you call CFrame.Angles. Consider creating the random values like this:
math.random() returns a value from 0 to 1 when called without arguments. math.random() * 2 - 1 gives a floating value from -1 to 1, instead of an integer. This will give you some shots landing between your 9 in your screenshot.
If you wanted to do a conic-type spread, this is more involved and requires some trigonometry. Try out that simple solution and see if it works for your game first.
If you’re choosing the X and Y coordinates independently, it’s always going to be in the shape of a box. If you want it to be in a cone/circle, the two coordinates are dependent. If the X has been chosen to be to the left, then there’s a limit to how low/high the Y coordinate can be.
You can choose a random point inside a circle, and use that in your RayCast function, like this:
local random = Random.new()
local function randomPointInCircle( radius )
local angle = random:NextNumber(0, math.pi*2)
return Vector2.new(
math.cos(angle),
math.sin(angle)
)
end
local function RayCast(Position, Direction, MaxDistance, IgnoreList)
local maxSpreadAngle = .5
local spreadAngles = randomPointInCircle( math.rad(maxSpreadAngle) ) * random:NextNumber(0, 1)
local spreadRay = Ray.new(Position,
CFrame.Angles(
spreadAngles.X,
spreadAngles.Y,
0 --Why rotate the ray around the Z axis?
) * ray.Direction
)
return game.Workspace:FindPartOnRayWithIgnoreList(spreadRay, IgnoreList)
end
print(randomPointInCircle(1))
Using your code as is seems to give me the error “Vector3 expected, got CFrame” on the spreadRay line. I’m probably just missing something, but I can’t figure out how to fix it. I think I got the same earlier from the code ozzypig suggested but adding the little *ray.Direction on the end fixed it. Unfortunately that doesn’t seem to do it this time
I’m not familiar with using that but I tried it without anything inside and adding a random number to go with it but both seem to just make bullets go all over the place lol
Well it seems no matter what I put in the maxSpreadAngle .001 to 1000+ the bullets just kinda seem to go in the general direction the player is looking maybe as if the radius is way bigger then it should be? idk sorry for all the trouble