How To Achieve Randomness in Raycasting

How do I achieve randomness in the X-axis for my RayCasting Results? I am trying to recreate a sense of bullet spread for my gun, I am unsure of where the randomized number should be inserted to.

Point.Position is the origin at which the Raycast will start.
PointLookVector is whatever direction the part is facing

local RaycastResult = workspace:Raycast(Point.Position, PointLookVector * 500, RaycastParams)

local function createSpread(cframe: CFrame, 
                            maxSpread: number): Vector3
    local randomX = math.random(1, maxSpread);
    local randomY = math.random(1, maxSpread);

    local cframe = cframe * CFrame.Angles(math.rad(randomX), 
                                  math.rad(randomY), 
                                  0);
    return cframe.LookVector
end

local maxSpread: number = 5;
local pointLook: CFrame = ...
local result = workspace:Raycast(point.Position,
                                 createSpread(pointLook, maxSpread) * 500,
                                 raycastParams)

In theory, it should take the target CFrame (the point we’re aiming at) and return it tilted by a random number between 1 and maxSpread on the X and Y axes. When we do this slight tilt, it will affect the Raycast such that it looks inaccurate.

I’m guessing this answers the previous question. The randomized number should be an angle that we apply to the target CFrame, and extract its LookVector.

1 Like

Just tested the script out and the error message returned invalid argument #1 (CFrame expected, got Vector3) .

I do not quite understand the Vector3’s role at this line
local function createSpread(cframe: CFrame, maxSpread: number): Vector3

What is the difference between the usage of Colons and Equal?

		local pointLook: CFrame = PointLookVector
 
		local Point = tool.Handle.ShootPoint1
		local PointLookVector  = Point.CFrame.LookVector

		local RaycastParams = RaycastParams.new()
		RaycastParams.FilterDescendantsInstances = {tool.Parent}
		RaycastParams.FilterType = Enum.RaycastFilterType.Exclude

		print(RaycastParams.FilterDescendantsInstances)
		local doDmgRE = tool:WaitForChild("DoDamage")
		
		
		
		local function createSpread(cframe: CFrame, maxSpread: number): Vector3
			local randomX = math.random(1, maxSpread)
			local randomY = math.random(1, maxSpread)

			local cframe = cframe * CFrame.Angles(math.rad(randomX), math.rad(randomY), 0);
			return cframe.LookVector
		end

		local maxSpread: number = 5
		local pointLook: CFrame = PointLookVector
		
		
		local RaycastResult = workspace:Raycast(Point.Position,createSpread(pointLook, maxSpread) * 500, RaycastParams)

It’s a Luau feature called “type-checking”. It promotes safety by not allowing incompatible types to mess with each other. When I added : Vector3 to the createSpread function’s definition, it means that createSpread will only ever return a Vector3.

When I marked pointLook as a CFrame, it means that variable only supports the CFrame type. The issue is that you tried to assign it a Vector3 (PointLookVector), which caused an error.

The fix? pointLook = Point.CFrame.

1 Like

I will come back to this tomorrow and update you. Currently there are still some direction issues with the CFrame.Angles(math.rad(randomX), math.rad(randomY), 0);
I will make an attempt to resolve it tomorrow and return with the results.

The issue: Raycast will go directly straight and most will stray off at a 45degree angle. This is an automatic weapons that is why each Raycast should vary in results by a small margin. I have already tried tweaking the degrees but it only messes things up. I do have a suspicion that I should use something else besides CFrame.Angles as my Raycast direction is wherever the gun’s barrel is aiming at. Perhaps LookAt? I am not sure…but I intend to make it so the Raycast will only stray either to the left or right to wherever the barrel is aiming.

1 Like

I am back, no resolution yet. I have taken a different route in approaching this issue but I have still yet to figure out an actual solution.

Currently, I have taken a much digestible code for my own understanding but the problem still persists. I am trying to make the bullets spread a bit, so as to make shooting less of a point and click.

local RaycastParams = RaycastParams.new()
        RaycastParams.FilterDescendantsInstances = {tool.Parent}
        RaycastParams.FilterType = Enum.RaycastFilterType.Exclude

        print(RaycastParams.FilterDescendantsInstances)
        local doDmgRE = tool:WaitForChild("DoDamage")
        
        local Point = tool.Handle.ShootPoint1
        
        local LookVector = Point.CFrame.LookVector
        local PointLookVector  = Point.CFrame.LookVector * CFrame.Angles(-20, 90, 0).LookVector
        

        
        
        local RaycastResult = workspace:Raycast(Point.Position,PointLookVector * 500, RaycastParams)