Projectile Collides while it's CanCollide is false

The title says it all. I don’t know why or how this happens. Even when their CanCollide is set to false, the projectiles in my game ricochet off of parts. Is there some other property that can be affecting this?

1 Like

Are there any related scripts that may affect the projectile in any way?

No, just one a ModuleScript called “Projectiles”

Can you show me the code for this modulescript?

Sorry for being afk, my Icelandic internet gave way:

local projectile = {}

local data = {
	Cannonball = {
		Model = projectilesFolder.Cannonball;
		Damage = 1000;
		Size = Vector3.new(2, 2, 2)
	};
	Musketball = {
		Model = projectilesFolder.Musketball;
		Damage = 150;
		Size = Vector3.new(0.144, 0.144, 0.144)
	};
	GatlingBullet = {
		Model = projectilesFolder.GatlingBullet;
		Damage = 25;
		Size = Vector3.new(0.105, 0.115, 0.205)
	};
	NavyBullet = {
		Model = projectilesFolder.GatlingBullet;
		Damage = 15;
		Size = Vector3.new(0.105, 0.115, 0.205)
	};
}

projectile.fire = function(plr : Player, LookVector : CFrame, projectileName : string, position : Vector3, speed : number, spread : number, ignore : SharedTable)
	if not data[projectileName] then return end
	
	local projectile = data[projectileName].Model:Clone()
	projectile.CFrame = CFrame.new(position)
	projectile.Parent = workspace.Projectiles
	projectile:SetNetworkOwner(plr)

	local BV = Instance.new("BodyVelocity")
	BV.Velocity = LookVector * speed
	BV.Parent = projectile
	BV.MaxForce = Vector3.new(math.huge, math.huge, math.huge)

	spawner(function()
		RS.Heartbeat:Connect(function(dt)
			local ray = Ray.new(projectile.CFrame.Position, ((projectile.CFrame * CFrame.new(0, 0, -300)).Position - projectile.CFrame.Position).Unit * 3)
			local part, position = workspace:FindPartOnRayWithIgnoreList(ray, ignore, false, true)
			if part and position and projectile then
				local cf = CFrame.new(position)
				local size = projectile.Size
				
				if part.Parent:FindFirstChild("Humanoid") then
					projectile:Destroy()
					part.Parent.Humanoid:TakeDamage(data[projectileName].Damage)
					--part.Transparency = 1
					part.Color = Color3.new(0.45, 0, 0)
					plr.leaderstats.Cash.Value += 15
				else
					projectile:Destroy()
				end
			end
		end)
	end)
end

return projectile

Using workspace:FindPartOnRay and workspace:FindPartOnRayWithIgnoreList is deprecated, you should use workspace:Raycast instead:

local projectile = {}
local data = {
	Cannonball = {
		Model = projectilesFolder.Cannonball;
		Damage = 1000;
		Size = Vector3.new(2, 2, 2)
	};
	Musketball = {
		Model = projectilesFolder.Musketball;
		Damage = 150;
		Size = Vector3.new(0.144, 0.144, 0.144)
	};
	GatlingBullet = {
		Model = projectilesFolder.GatlingBullet;
		Damage = 25;
		Size = Vector3.new(0.105, 0.115, 0.205)
	};
	NavyBullet = {
		Model = projectilesFolder.GatlingBullet;
		Damage = 15;
		Size = Vector3.new(0.105, 0.115, 0.205)
	};
}

projectile.fire = function(plr : Player, LookVector : CFrame, projectileName : string, position : Vector3, speed : number, spread : number, ignore : SharedTable)
	if not data[projectileName] then return end

	local projectile = data[projectileName].Model:Clone()
	projectile.CFrame = CFrame.new(position)
	projectile.Parent = workspace.Projectiles
	projectile:SetNetworkOwner(plr)

	local BV = Instance.new("BodyVelocity")
	BV.Velocity = LookVector * speed
	BV.Parent = projectile
	BV.MaxForce = Vector3.new(math.huge, math.huge, math.huge)

	spawner(function()
		RS.Heartbeat:Connect(function(dt)
			local raycastParams = RaycastParams.new()
			raycastParams.FilterDescendantsInstances = ignore
			raycastParams.FilterType = Enum.RaycastFilterType.Exclude

			-- You might need to adjust the direction (The second argument of workspace:Raycast)
			local raycastResult = workspace:Raycast(projectile.Position, projectile.CFrame.LookVector * 300, raycastParams)

			if raycastResult then
				local part, position = raycastResult.Instance, raycastResult.Position

				local cf = CFrame.new(position)
				local size = projectile.Size

				if part.Parent:FindFirstChild("Humanoid") then
					projectile:Destroy()
					part.Parent.Humanoid:TakeDamage(data[projectileName].Damage)
					--part.Transparency = 1
					part.Color = Color3.new(0.45, 0, 0)
					plr.leaderstats.Cash.Value += 15
				else
					projectile:Destroy()
				end
			end
		end)
	end)
end

return projectile

You might need to edit the direction (It’s the second argument of workspace:Raycast), as I’ve set it up so that the raycast uses the projectile’s LookVector as the direction, and you also might need to edit the raycast’s magnitude (The 300 I’m multiplying with the direction) if they don’t match how your original script behaved

How will that help my problem?

I misinterpreted the problem as FindPartOnRayWithIgnoreList detecting parts even though it shouldn’t, but I’d still recommend replacing deprecated functions whenever possible

You could try adding the projectiles into their own collision group:

Thanks for that, but I do need to do some work on the direction. The bullets kill NPCs from all the way across the map :laughing:

1 Like

or its the ricochet :person_shrugging: character limit

CollisionGroups? Never tried that

1 Like

It could be that the ricochet isn’t bouncing the projectile off the object correctly, if the projectile’s orientation isn’t changed that much when they hit an object it would explain why they’re able to travel a great distance

They’re quite useful when dealing with assemblies that use a lot of physics constrains as well :slight_smile::+1:

There is supposed to be NO ricochet, that’s what I’m trying to remove

Having the projectiles in their own collision group will prevent them from being able to hit other parts (so long as the collision group is configured correctly), which would fix the ricochet issue, unless you do want the projectiles to hit other parts

As for why the raycast is able to hit people from great distances, if the issue isn’t being caused by the ricochet (as I explained in my previous comment), then either you’d need to change the 300 to a smaller value, or something else is causing the raycast to be extended

I set up the CollisionGroup so that it would not collide with ANYTHING. Is that ideal, because my game lags more now?

It most definitely should’nt have caused your game to lag, if anything it should’ve improved the performance by a bit since the engine no longer needs to calculate collisions for the projectiles

I’ve also identified a possible cause for the long distance hit issue, and I’m working on a fix now


@Henscantfly

This should fix the long distance issue:

local projectile = {}
local data = {
	Cannonball = {
		Model = projectilesFolder.Cannonball;
		Damage = 1000;
		Size = Vector3.new(2, 2, 2)
	};
	Musketball = {
		Model = projectilesFolder.Musketball;
		Damage = 150;
		Size = Vector3.new(0.144, 0.144, 0.144)
	};
	GatlingBullet = {
		Model = projectilesFolder.GatlingBullet;
		Damage = 25;
		Size = Vector3.new(0.105, 0.115, 0.205)
	};
	NavyBullet = {
		Model = projectilesFolder.GatlingBullet;
		Damage = 15;
		Size = Vector3.new(0.105, 0.115, 0.205)
	};
}

projectile.fire = function(plr : Player, LookVector : CFrame, projectileName : string, position : Vector3, speed : number, spread : number, ignore : SharedTable)
	if not data[projectileName] then return end

	local projectile = data[projectileName].Model:Clone()
	projectile.CFrame = CFrame.new(position)
	projectile.Parent = workspace.Projectiles
	projectile:SetNetworkOwner(plr)

	local BV = Instance.new("BodyVelocity")
	BV.Velocity = LookVector * speed
	BV.Parent = projectile
	BV.MaxForce = Vector3.new(math.huge, math.huge, math.huge)

	spawner(function()
		local overlapParams = OverlapParams.new()
		overlapParams.FilterDescendantsInstances = ignore
		overlapParams.FilterType = Enum.RaycastFilterType.Exclude

		local originalPosition = projectile.Position

		local connection
		connection = RS.Heartbeat:Connect(function(dt)
			if (projectile.Position - originalPosition).Magnitude >= 300 then
				connection:Disconnect()
				projectile:Destroy()
				return
			end

			for _, part in workspace:GetPartsInPart(projectile, overlapParams) do
				local model = part:FindFirstAncestorOfClass("Model")

				if model then
					local humanoid = model:FindFirstChildOfClass("Humanoid")

					if humanoid then
						humanoid:TakeDamage(data[projectileName].Damage)
						part.Color = Color3.new(0.45, 0, 0)
						plr.leaderstats.Cash.Value += 15
					end
				end
			end

			connection:Disconnect()
			projectile:Destroy()
		end)
	end)
end

return projectile

Essentially what was causing it was that since the projectile is a moving object and the raycast is originating from its current position, and the raycast was being fired inside of a loop, the raycast was extending beyond the 300 distance that was originally intended

Using workspace:GetPartsInPart should also make the collision detection for the projectile more accurate than when using raycasts

If can collide is false, the parts shouldn’t interact with other parts, unless:

  • They are connected to parts with can collide on
  • There is code that detects parts any programmatically causes them to ricochet

CanCollide being off overrides all collision group settings.

The projectiles just never appear, i think the connection messed my code up and I’m narrowing down the problem

That would mean that the projectiles are already 300 studs past the original position that they were when originally fired

I don’t know how you’re handling the projectile’s movement, and the programming style/system you’re using is significantly different than the one I use, which is why I’m getting confused :sweat_smile:

I use a more rough approach to programming, and I notice you use a more cautious approach. I have never really used connections, so I think that’s why the code messed up

1 Like