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