How do I make a gun that can shoot through objects with collide off

I’m trying to make a simple gun that can shoot through objects that are cancollide off.
This is easier said than done.

I have tried making a gun with BodyVelocity, and I have tried raycasting.

I’m not going to be using BodyVelocity (unless there is a solution for my problems with it), since sometimes the bullets are so fast they just go through regular parts and they, for some reason when I fire them, are always a few studs away from the gun.

I tried raycasting. I don’t really have a problem with it, but I can’t manage it to make the raycast somehow go through a part that has collide off. I tried blacklisting it, using ignorelist, they all don’t work and it’s probably because I’m doing something wrong. However when I create a topic and someone gives me a solution, I ask them a question about how I would do this, and they don’t respond.

I have been searching for an entire month. I’m not asking you to create an entire gun system for me, I’m asking how I could do this, and when I ask a question I would appreciate a response.

Sorry for any grammar mistakes in advance. English is not my main language.

i’d suggest you put your script in the post, that way other users can help you more.

You can Raycast recursively if the hit part has collision set to false. Here is a small function I used in my Mini-map rendering script, it has been modified a bit to work for your use case.

local Params = RaycastParams.new()
local function RecursiveRaycasting(Origin,Direction)
	local Result = workspace:Raycast(Origin,Direction,Params)

	if (not Result) then
		return nil,(Origin+Direction),Default,Enum.Material.Air
	end

	if ((Result.Instance.ClassName == "Terrain") or (Result.Instance.CanCollide)) then
		return Result.Instance,Result.Position,Result.Normal,Result.Material
	end
	
	local Direction = (Origin+Direction)-Result.Position
	
	return RecursiveRaycasting(
		(Result.Position+(Direction.Unit*0.1)),
		(Direction)
	)
end

This works exactly like workspace:FindPartOnRay, you just need to replace workspace:FindPartOnRay with RecursiveRaycasting instead.

If you are using workspace:Raycast you need to edit the function to return the RaycastResult instead of its values.

Logic is simple:

If the ray hits a uncollide part, it will fire another ray in the same direction, and the origin being the hit_point of the uncollide part, and repeat this until it finds a collidable part or nil, perhaps to stay on the safe side, you could add a max number of Raycasts so it doesn’t possibly glitch out and Raycast indefinitely and crash the server/client. That’s very unlikely to happen but still.

1 Like

The most simple solution is to apply filtered descendants to the raycastParams:

It will simply skip the hits on those parts that doesn’t have any collision on, if you correctly added the right parts to it. According to the parameters, it is a table and you should include the objects in the table and then raycast with the parameters.

Alternatively, setting CollisionGroup seems to be a plausible solution, if there are many parts which are astray in the game.

1 Like

If you only want to shoot trough objects that are cancollide false, make the bullets the same collission group as the objects. (Most likely create a loop for all parts to achieve this)

1 Like

I will test these things out, however I can’t right now due to me not being able to access Roblox at this time.

1 Like

All right, i’m just saying because it’s not allowed for users to make scripts for you. I hope you find your answer! :relaxed:

1 Like

I’m finally back! I was suffering from internet issues. At this point I don’t really expect any response, I don’t blame you. It’s been 3 damned days.

This is the script I created. I’m doing something wrong since I doesn’t seem to shoot anything or damage anything.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local event = ReplicatedStorage:WaitForChild("GunEvents").Prototype_Gun
local physicsService = game:GetService("PhysicsService")
physicsService:CreateCollisionGroup("blacklistedParts")
physicsService:CreateCollisionGroup("raycastGroup")
physicsService:SetPartCollisionGroup(workspace.TestGlass, "blacklistedParts")
physicsService:CollisionGroupSetCollidable("raycastGroup", "blacklistedParts", false)

local RayParams = RaycastParams.new()
RayParams.FilterType = Enum.RaycastFilterType.Blacklist
RayParams.IgnoreWater = true
RayParams.CollisionGroup = "raycastGroup"

event.OnServerEvent:Connect(function(Player, GunPos, MouseP, Handle)
	Handle.Fire:Play()
	
	local RayCast = workspace:Raycast(GunPos, MouseP*1000, RayParams)
	
	if RayCast then
		local hum = RayCast.Instance.Parent:FindFirstChild("Humanoid") or RayCast.Instance.Parent.Parent:FindFirstChild("Humanoid")
		if hum then
			hum:TakeDamage(25)
		end		
		
		local bullet = Instance.new("Part")
		bullet.CanCollide = false
		bullet.Anchored = true
		bullet.BrickColor = BrickColor.new("Cool yellow")
		bullet.Material = Enum.Material.Neon

		local Dist = (GunPos-RayCast.Position).magnitude
		bullet.CFrame = CFrame.new(GunPos, RayCast.Position)*CFrame.new(0,0,-Dist/2)
		bullet.Size = Vector3.new(0.1, 0.1, Dist)
		game.Debris:AddItem(bullet, 0.5)
	end
	
end)