Issue With Raycasting

Hey Developers!

I’d appreciate some help here with a (probably simple) raycasting issue. I am scripting a shotgun and have finally gotten the spread math to work in a conical shape but the hit detection seems to be completely off. Let me show you my code:

local function FireGun()
	local OriginPos = (Handle.CFrame * CFrame.new(0, Handle.Size.Y/2, -Handle.Size.Z/2 - 0.25)).Position;
	local MouseHit = Mouse.Hit;
	local MousePos = MouseHit.Position;
	
	local Beams = {}
	
	for i = 1, NUM_SHOTS do
		local SteppedAngle = i * 360/NUM_SHOTS;
		
		local OffsetX = (SPREAD_RADIUS * math.cos(SteppedAngle));
		local OffsetY = (SPREAD_RADIUS * math.sin(SteppedAngle));
		
		local aDir = (Mouse.Hit.Position - OriginPos).Unit * DISTANCE;
		local bDir = (Mouse.Hit.Position - OriginPos).Unit * SPREAD_AMOUNT;
		local xDir = CFrame.new(OriginPos + bDir, OriginPos + aDir);
		
		local Direction = OriginPos + ((xDir * CFrame.new(OffsetX, OffsetY, 0)).Position - OriginPos).Unit;
		
		local NewRay = Ray.new(OriginPos, Direction);
		local Part, HitPos = workspace:FindPartOnRay(NewRay);
		
		local x = Instance.new("Part");
		x.Size = Vector3.new(0.5, 0.5, 0.5);
		x.Anchored = true;
		x.BrickColor = BrickColor.Red();
		x.CFrame = CFrame.new(NewRay.Origin);
		x.CanCollide = false;
		x.Parent = MouseFilter;
			
					local x = Instance.new("Part");
			x.Size = Vector3.new(0.05, 0.05, 0.05);
			x.Anchored = true;
			x.Material= Enum.Material.Neon
			x.BrickColor = BrickColor.Green()
			x.CFrame = CFrame.new(NewRay.Direction);
			x.CanCollide = false;
			x.Parent = MouseFilter;
			
			local x = Instance.new("Part");
			x.Size = Vector3.new(1, 1, 1);
			x.Anchored = true;
			x.Material= Enum.Material.Neon
			x.BrickColor = BrickColor.Blue()
			x.CFrame = CFrame.new(HitPos);
			x.CanCollide = false;
			x.Parent = MouseFilter
		
		--if true then return end
		
		local Dist = DISTANCE;
		
		if Part then
			Dist = (OriginPos - HitPos).Magnitude;
		end
		
		local Beam = Instance.new("Part");
		Beam.Size = Vector3.new(0.2, 0.2, Dist);
		Beam.Anchored = true;
		Beam.CanCollide = false;
		Beam.BrickColor = BrickColor.new("Dark stone grey");
		Beam.Material = Enum.Material.SmoothPlastic;
		Beam.Transparency = 0.6;
		
		Beam.CFrame = CFrame.new(NewRay.Origin, NewRay.Direction) * CFrame.new(0, 0, -Dist/2);
		
		Beam.Parent = MouseFilter;
		
		delay(2, function()
			local Tween = TweenService:Create(Beam, TweenInfo.new(0.5), {Transparency = 1});
			Tween:Play();
			
			Tween.Completed:Connect(function()
				Beam:Destroy();
			end)
		end)
		
		table.insert(Beams, Beam);
	end
end

(This is a function called when a Tool is activated, Currently no serverside code as I’m still trying to get the math right)

In the following GIF you can see the apparent problem:
https://gyazo.com/285df9f85603ebd449ee44f67312609f

The blue blocks are spawned at HitPos, which is taken straight from the FindPartOnRay. The Red blocks are spawned at the origin of the ray, while the green ones show the direction of each bullet.

My issue is, why are the blue blocks completely off? You can see that my casted trails are accurate as they derive their positions straight from the original casted ray; so no problem there. I’m at my wits end with this and have been trying to fix it for hours now and just can’t see the problem. I would really appreciate any help. Thanks!

bricknemesis

No collision groups. Besides, the rays keep thinking that they’re hitting something way off where I was aiming, and the visualisation of the ray says the exact opposite of that. I swear my math isn’t wrong…

1 Like

Try making a visualized raycast that is the length of the magnitude (divided by 2 then make it negative) of the origin and hit position. If you’re confused, you can ask me how to create the visualization further.

Check near the end of the code. I do this. I’ve also done from the origin to the hit pos, it shows me nothing that I don’t already know. I have no idea why this is entirely screwed up…

You’re just setting the CFrame of a direction vector and the other positions, I mean like an actual long part that looks like a ray. Those are just blocks representing position points.

Instead of using:

local Part, HitPos = workspace:FindPartOnRay(NewRay);

You should probably use:

local Part, HitPos = workspace:FindPartOnRayWithIgnoreList(NewRay,Ignorelist);

By having an array of parts to ignore, your HitPos and part returned will not be anything in the table, Ignorelist.

Also you can try adding parts to a collision group, other than the default one - and those parts will be ignored, a well, using this method, as noted in the link:

Roblox API docs of FindPartOnRayWithIgnoreList

Hi,

I’ve already tried using WithIgnoreList. The hit detection is just totally messed up!!! I don’t know why