Setting CanCollide = true isn't consistent

I’m making a bomberman game and I have a three scripts

One is a serverscript that places bombs, listens for a remote event to change the collision, and fires a remote event to check how far the player is from the bomb they placed:

game.ReplicatedStorage.Events.PlaceBomb.OnServerEvent:Connect(function(player: Player, tile: BasePart, blastRadius)
	tile:SetAttribute("Bomb", true)
	local BombName = player.Name .. #game.Workspace.Bombs:GetChildren()
	local TileIndex = table.find(game.Workspace.Floor:GetChildren(), tile)
	
	local BombClone = game.ReplicatedStorage.Timebomb:Clone()
	BombClone.Name = BombName

	BombClone.Parent = game.Workspace.Bombs
	BombClone.CFrame = CFrame.new(tile.Position) * CFrame.new(0, 4, 0) * CFrame.Angles(math.rad(-90), 0, 0)

	local TimebombScript = script.Explode:Clone()
	TimebombScript.Parent = BombClone
	TimebombScript.BlastRadius.Value = blastRadius
	
	TimebombScript.Disabled = false
	game.ReplicatedStorage.Events.ActivateCollision:FireClient(player, BombName, TileIndex)
	
	BombClone.Destroying:Connect(function()
		tile:SetAttribute("Bomb", false)
	end)
end)

game.ReplicatedStorage.Events.ActivateCollision.OnServerEvent:Connect(function(player: Player, bombName: string)
	game.Workspace.Bombs[bombName].CanCollide = true
	game.Workspace.Bombs[bombName].Outline.CanCollide = true
end)

The second is a server script that is a child of the bomb which counts down, destroys bricks in the blast radius:

local bombTick = 16
local waitTime = 0.3
local active = true

local explosionRow = 1
local directionStopped = {}

local CollectionService = game:GetService("CollectionService")

local Mesh: SpecialMesh = script.Parent.Mesh
local Part: BasePart = script.Parent

Part.Audio.Place:Play()

while active do
	wait(waitTime)
	if bombTick < 10 then
		waitTime = 0.15
	end	

	if Part.Outline.Transparency == 1 then
		Part.Outline.Transparency = 0
	else
		Part.Outline.Transparency = 1
		--Part.Audio.Tick:Play()
	end

	bombTick -= 1

	if bombTick == 0 then
		active = false
	end
end

local function getEntitiesInRadius(origin, radius)
	local entities = {}

	local rootParts = CollectionService:GetTagged("HumanoidRootParts")
	for i, part in pairs(rootParts) do
		if (part.Position - origin).magnitude <= radius then
			local Humanoid: Humanoid = part.Parent.Humanoid

			Humanoid:TakeDamage(100)
			table.insert(entities, part.Parent) --Inserting the character into the 'entities' table
		end
	end

	return entities
end


while active == false do
	if script.Parent.Transparency ~= 1 then
		Part.Audio.Explosion1:Play()
		Part.Audio.Explosion2:Play()
		
		Part.Transparency = 1
		Part.CanCollide = false

		local Explosion = game.ReplicatedStorage.Particles.Explosion:Clone()
		Explosion.Parent = Part

		getEntitiesInRadius(Part.Position, 3)

		Explosion:Emit()
	end

	for i, detector: BasePart in ipairs(Part.ExplosionRows[tostring(explosionRow)]:GetChildren()) do
		local row = Part.ExplosionRows[tostring(explosionRow)]
		if detector:IsA("BasePart") then
			if table.find(directionStopped, detector.Name) == nil then
				if #detector:GetTouchingParts() ~= 0 then
					for i, object: BasePart in ipairs(detector:GetTouchingParts()) do
						if object.CollisionGroup == "Indestructable" then
							table.insert(directionStopped, detector.Name)

							detector:Destroy()
							detector = nil
						elseif object.CollisionGroup == "Destructable" then
							object:Destroy()
						end
					end
				end
			else
				detector:Destroy()
			end

			if detector ~= nil then
				local Explosion = game.ReplicatedStorage.Particles.Explosion:Clone()

				Explosion.Parent = detector
				getEntitiesInRadius(detector.Position, 3)
				Explosion:Emit()
			end
		end
	end
	explosionRow += 1

	if explosionRow == script.BlastRadius.Value + 1 then
		wait(2)
		script.Parent:Destroy()
	end

	wait(0.05)
end

The last is a local script that fires a remote event to place a bomb, and it also listens for the remote event to check how far the player is:

local PlayerStatus = require(script.Parent)

local Player = game.Players.LocalPlayer
local UIS = game:GetService("UserInputService")
local Mouse = Player:GetMouse()

local mouseHover = nil

local BlastRadius = 1
local MaxBombs = 1

local Kick = false

local PlayerPos = 0

local ClosestTile: BasePart = nil



Player.CharacterAdded:Connect(function(character)
	PlayerPos = character:WaitForChild("HumanoidRootPart").Position
end)

Mouse.TargetFilter = game.Workspace:WaitForChild("Non-Selectable")
Mouse.Move:Connect(function()
	if Mouse.Target ~= nil then
		if Mouse.Target.CollisionGroup == "Placeable" then
			mouseHover = Mouse.Target
		else
			mouseHover = nil
		end
	else
		mouseHover = nil
	end
end)

Mouse.Button1Down:Connect(function()
	PlayerPos = Player.Character:WaitForChild("HumanoidRootPart").Position
	
	for i, tile: BasePart in ipairs(PlayerStatus.TileStanding) do
		if ClosestTile == nil then
			ClosestTile = tile
		else
			if (PlayerPos - ClosestTile.Position).Magnitude < (PlayerPos - tile.Position).Magnitude then
				ClosestTile = tile
			end
		end
	end
	
	if not ClosestTile:GetAttribute("Bomb") then
		print("PlacedBomb")
		
		game.ReplicatedStorage.Events.PlaceBomb:FireServer(ClosestTile, BlastRadius)
	else
		print("Tile Occupied")
	end
	
	ClosestTile = nil
end)

local Debounce = false

game.ReplicatedStorage.Events.ActivateCollision.OnClientEvent:Connect(function(bombName: string, tile: BasePart)
	local checkCollision = true
	
	local Part: BasePart = game.Workspace.Bombs[bombName]
	
	while checkCollision do
		if (Player.Character.HumanoidRootPart.Position - Part.Position).Magnitude < 4 then
			wait(0.05)
		else
			checkCollision = false
		end
	end
	game.ReplicatedStorage.Events.ActivateCollision:FireServer(bombName)
end)

I want to have it so that when a bomb is placed, it’s placed on the tile the player is standing on, and the collision is disabled until they leave this tile.

For some reason the collision is only activated sometimes:

In this code I use .Magnitude, but I’ve also used .TouchedEnded before and the same issue persists.

Also let me know if I left something out, I kinda threw this post together in a hurry lol

3 Likes

I have solved this issue, instead of setting the collision to true on the server, an event is fired to every player which will set the collision locally when they leave the area

For some reason the event that’s fired to tell the server to set the collision was constantly being eaten.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.