Help with raycasting

I’m making a bullet system where the player can shoot through walls to hit other players however the bullet is inaccurate and doesn’t follow a straight path

local module = {}

local aliveTime = 1

local raycastModulePTP = require(game.ServerStorage.Server_Modules:FindFirstChild("Raycast(PartToPart)"))
local raycastModuleDir = require(game.ServerStorage.Server_Modules:FindFirstChild("Raycast(Direction)"))
local dbs = game:GetService("Debris")


local function DetectCamera(part)
	if part:GetAttribute("Camera") then
		part.Parent.Parent:FindFirstChild("Break").Value = true
	end
end

local function EffectHumanoid(firer, Bullet, damage)
	local Player = firer
	local touchingParts = game:GetService("Workspace"):GetPartsInPart(Bullet)
	print(touchingParts)
	for _, part in ipairs(touchingParts) do
		if part.Parent:FindFirstChild("Humanoid") then
			local humanoid = part.Parent:FindFirstChild("Humanoid")
			humanoid.Health -= damage
			print(part.Parent.Name.. " Has been hit")
			print("Rig health: ".. humanoid.Health)
		end
	end
end

local function Detect(Bullet, firer, damage,range,gun, from, direction)
	local touchingParts = game:GetService("Workspace"):GetPartsInPart(Bullet)
	print(touchingParts)
	
	EffectHumanoid(firer,Bullet, damage)
	
	for _, part in ipairs(touchingParts) do
		
		DetectCamera(part)
		
		if part:GetAttribute("NBC") then
			local ThroughMarker = Instance.new("Part")
			ThroughMarker.Name = "Passthrough"
			ThroughMarker.Size = Bullet.Size
			ThroughMarker.Color = Color3.fromRGB(255, 225, 0)
			ThroughMarker.Transparency = 1
			ThroughMarker:SetAttribute("BulletBox", true)
			ThroughMarker.Position = Bullet.Position
			ThroughMarker.Orientation = Bullet.Rotation
			ThroughMarker.Shape = Bullet.Shape
			ThroughMarker.Anchored = true
			ThroughMarker.Parent = game.Workspace.Ignored_Parts
			dbs:AddItem(ThroughMarker, aliveTime)
			local params = RaycastParams.new()
			params.IgnoreWater = true
			params.FilterType = Enum.RaycastFilterType.Exclude
			params.FilterDescendantsInstances = {workspace.Ignored_Parts, firer.Character, gun, part}
			local ThroughBullet = Instance.new("Part")
			ThroughBullet.Name = "Passthrough bullet"
			ThroughBullet.Anchored = true
			ThroughBullet.CanCollide = false
			ThroughBullet.Transparency = 0
			ThroughBullet:SetAttribute("BulletBox", true)
			ThroughBullet.Color = Color3.fromRGB(0, 255, 0)
			ThroughBullet.Size = Bullet.Size * 5
			ThroughBullet.Shape = Bullet.Shape

			print(tostring(from))
			print(tostring(direction))
			ThroughBullet.Position = raycastModuleDir.Raycast(from, direction, params, range).Position
			ThroughBullet.Parent = game.Workspace.Ignored_Parts
			
			EffectHumanoid(firer, ThroughBullet, damage / 2)
			dbs:AddItem(ThroughBullet, aliveTime)
		end
	end
end

function module.FireBullet(Firer, gun, To, From, BulletSize, damage, range)
	local BulletHitbox = Instance.new("Part")
	BulletHitbox.Anchored = true
	BulletHitbox.CanCollide = false
	BulletHitbox.Transparency = 1
	BulletHitbox.Color = Color3.fromRGB(0, 0, 0)
	BulletHitbox.Size = Vector3.new(BulletSize, BulletSize, BulletSize)
	BulletHitbox.Shape = Enum.PartType.Ball
	
	local damageINT = Instance.new("IntValue")
	damageINT.Value = tonumber(damage)
	damageINT.Name = "Damage"
	damageINT.Parent = BulletHitbox
	BulletHitbox:SetAttribute("BulletBox", true)
	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Exclude
	params.FilterDescendantsInstances = {workspace.Ignored_Parts, Firer.Character, gun}
	print(To)
	local intersection = raycastModulePTP.Raycast(From,To.Position, params, range).Position
	BulletHitbox.Position = intersection
	local part = Instance.new("Part")
	part.Shape = Enum.PartType.Ball
	part.Size = Vector3.new(0.1,0.1,0.1)
	part.Position = To.Position
	part.Anchored = true
	part.Color = Color3.fromRGB(0,255,0)
	part.Parent = workspace.Ignored_Parts
	BulletHitbox.Parent = game.Workspace.Ignored_Parts
	dbs:AddItem(BulletHitbox, aliveTime)
	Detect(BulletHitbox, Firer, damageINT.Value,range,gun, intersection, To.Position)
end

return module

4 Likes

Hello there, I’ll try to help you out with Raycasting!

However I’m slightly confused, from what I see the Raycast is working? I don’t know exactly what you mean so could you clarify?

don’t use ipairs/pairs plz :pray:
Just keep raycasting untill there is nothing to hit/hit the player
And do AddToFilter to remove wall from raycast

2 Likes

the second red box on the other side of the wall is inaccurate, it should line up with the original box, acting like a bullet shooting through a wall

1 Like

Oh, I guess like what Yarik said, just use Raycast Parameters, you can exclude the wall so the Raycast doesn’t hit the wall at all.

Of course if you’re planning to do something on the wall like shattering glass then you’re going have to do a different method, just let me know if you’re going to do that!

I need it to hit the wall because its a check to decrease the bullets damage and range

1 Like

Nothing wrong with using it. It can be useful for demonstrating if you expect the table to be array-like or dictionary-like.

Anyway, @ImagineThePosibiIity where are the From and To values being calculated? Since this issue is related to directions, that seems like a relevant portion of the code to include here. As in, please include the code where you’re calling FireBullet.

A couple other questions.

  1. What’s the purpose of DetectCamera?
  2. Is it necessary to do a GetPartsInPart in both EffectHumanoid and in Detect?

It seems weird to be using GetPartsInPart in combination with raycasting. Typically you would just do a raycast or a shapecast and use the resulting hit from that cast, unless this is for a custom explosive projectile or something that requires an area check at the destination.

Might be worth including your raycast module code here too.

1 Like

Ipairs/pairs behave almost exactly the same as regular iterstion cycle; look at benchmarks using ipairs/pairs is a bit slower than not using them (ironically)
Ipairs is only useful to stop cycle if there is a gap other than that never use them

1 Like

Alright, all you really have to do is get the direction the Raycast was shot from.

To do this, you could try to make a variable of where the player originally fired? I tried reading your script but it’s really messy and hard to read… And also I can’t really read the Raycast module, didn’t mean to be rude by the way.

Anyways if you could tell me where this wallbang feature is located within the code maybe I could help more, really sorry if this comes out rude by the way as that is not my intentions!


Also I agree somewhat agree with @BusyCityGuy, however I’d recommend firing multiple Raycasts if you use this method as I assume you want multiple targets to get hit as from the for loop.

Of course nothing wrong with the current method but you can exclude stuff with Raycasting.