Tools with projectiles & object cloning/creating broken when cloned

So, I’m trying to make tools that fire projectiles, and I also have a time bomb tool. All of them are in ServerStorage and have a prefab for the projectile/weapon body that gets cloned and set to the CFrame.

I’m gonna use just the time bomb for this post since whatever solution there may be will probably fix the others as well.
But the issue I have is only when the tool is cloned out of ServerStorage and into the player’s backpack. This is done on the server via ModuleScript for the round. The time bomb and other tools still clone the prefab for it, but it does NOT change the CFrame or position accordingly. The rest of the code works, it’s just the CFrame that isn’t being set. The tools work 100% perfectly fine when cloned by hand in test mode or if it was in StarterGear.
And also, all of the code for the time bomb was written myself. That is at the bottom of the post.

I’ve looked through old posts on the DevForum, but not of them were similar to my issue or their solution had deprecated solutions that would not work.
I’ve also tried disabling the script in the tool and enabling it when it’s cloned into the player’s backpack.


Screenshots of the game setup:

image

image

image

image


Here’s the code:

Specific lines in the round module:

local toolPack = replicatedStorage.MainGame.Tools.WeaponPacks:FindFirstChild(plr.EquippedPack.Value)
unpackageTools(plr, toolPack)

The entire round script:

local Players = game:GetService("Players")
local replicatedStorage = game:GetService("ReplicatedStorage")
local lighting = game:GetService("Lighting")
local tweenService = game:GetService("TweenService")
local serverStorage = game:GetService("ServerStorage")
local soundService = game:GetService("SoundService")
local marketPlaceService = game:GetService("MarketplaceService")

local musicFolder = soundService:WaitForChild("GameMusic")
local otherSounds = soundService:WaitForChild("OtherSounds")

local maps = serverStorage:WaitForChild("MainGame"):WaitForChild("Maps")

local mainGame = replicatedStorage:WaitForChild("MainGame")
local remotes = mainGame:WaitForChild("Remotes")
local gameValues = mainGame:WaitForChild("GameValues")

local status = gameValues:WaitForChild("Status")

local cashReward = 75
local expReward = 50

local function toMS(s)
	return ("%02i:%02i"):format(s/60%60, s%60)
end

local function unpackageTools(player, pack)
	local clone = pack:Clone()
	clone.Parent = player

	for _, tool in pairs(clone:GetChildren()) do
		tool.Parent = player.Backpack
		
		for __, Script in pairs(tool:GetDescendants()) do
			if Script:IsA("Script") and Script.Enabled == false then
				Script.Enabled = true
			end
		end
	end

	clone:Destroy()
end

local round = {}

function round.Waiting(numberOfPlayers, minimumPlayers)
	status.Value = minimumPlayers.." ready players are required to start ("..numberOfPlayers.."/"..minimumPlayers.." players)"
end

function round.Intermission(intermissionTime)
	for i=intermissionTime,0,-1 do
		status.Value = "Intermission ("..i..")"
		task.wait(1)
	end

end

function round.StartRound(gameLength)
	status.Value = ""

	local plrs = {}

	for i, player in pairs(Players:GetPlayers()) do
		table.insert(plrs,player)
	end

	task.wait(2)
	
	local availableSongs = soundService:WaitForChild("GameMusic"):GetChildren()
	local chosenSong = availableSongs[math.random(1,#availableSongs)]
	
	local availableMaps = maps:GetChildren()
	local chosenMap = availableMaps[math.random(1,#availableMaps)]

	status.Value = chosenMap.Name.." was selected"

	task.wait(2)

	local newMap = chosenMap:Clone()
	newMap.Name = chosenMap.Name
	newMap.Parent = workspace

	local spawnPoints = newMap:FindFirstChild("SpawnPoints")

	if not spawnPoints then
		warn("Critical Error: There are no spawn points in "..chosenMap.Name.."!")
	end

	local availableSpawns = spawnPoints:GetChildren()

	for i=5,0,-1 do
		status.Value = "Game will start in "..i
		task.wait(1)
	end
	
	remotes:WaitForChild("RoundMusic"):FireAllClients(chosenSong, "On")

	for i, plr in pairs(plrs) do
		if plr then
			local character = plr.Character

			coroutine.resume(coroutine.create(function()
				if not character then 
					plr:LoadCharacter()
					wait(0.1)
					character = plr.Character
				end

				wait(1.2)

				character.HumanoidRootPart.Position = availableSpawns[1].Position + Vector3.new(0, 8, 0)

				local hitbox = serverStorage.MainGame.Prefabs.Hitbox:Clone()
				hitbox.Parent = character
				hitbox.CFrame = character.HumanoidRootPart.CFrame

				local weld = Instance.new("Weld")
				weld.Parent = hitbox
				weld.Part0 = hitbox
				weld.Part1 = character.HumanoidRootPart
				
				local toolPack = replicatedStorage.MainGame.Tools.WeaponPacks:FindFirstChild(plr.EquippedPack.Value)
				unpackageTools(plr, toolPack)

				local gameTag = Instance.new("BoolValue")
				gameTag.Name = "GameTag"
				gameTag.Parent = character
			end));
		else
			if not plr then
				table.remove(plrs,i)
			end
		end

	end

	wait(1.3)

	for i=gameLength,0,-1 do
		for x, player in pairs(plrs) do
			if player then
				local character = player.Character

				if not character then
					table.remove(plrs,x)
				else
					if character:FindFirstChild("GameTag") then
						--Still in game
						continue
					else
						table.remove(plrs,x)
						player.leaderstats.Cash.Value += 5
						player.leaderstats.Level.CurrentExp.Value += 10
					end
				end
			else
				table.remove(plrs,x)
			end

		end

		status.Value = "Time: "..toMS(i).." remaining"

		if #plrs == 1 then
			status.Value = "Cleaning Up: Say congrats to the survivor!"

			task.wait(4)

			status.Value = ""

			plrs[#plrs].leaderstats.Cash.Value += cashReward
			plrs[#plrs].leaderstats.Level.CurrentExp.Value += expReward

			plrs[#plrs].leaderstats.Wins.Value += 1

			break
		elseif #plrs == 0 then
			status.Value = "Restarting: No one survived."
			break
		elseif i == 0 then
			status.Value = "Restarting: Time has run out."
			break
		end

		wait(1)
	end

	wait(1.5)

	for i, player in pairs(Players:GetPlayers()) do
		local character = player.Character

		if not character then
			continue
		else
			if character:FindFirstChild("GameTag") then
				character.GameTag:Destroy()
			end

			for _, tool in pairs(player.Backpack:GetChildren()) do
				if tool:IsA("Tool") then
					tool:Destroy()
				end
			end

			for _, tool in pairs(character:GetChildren()) do
				if tool:IsA("Tool") then
					tool:Destroy()
				end
			end

		end

		player:LoadCharacter()
	end

	table.clear(plrs)
	
	chosenSong:Stop()
	soundService.OtherSounds.Birds:Play()

	status.Value = "Cleaning up map..."

	wait(3)

	newMap:Destroy()

	wait(7)
end

return round

Server code running the module:

-- >>: Round
coroutine.resume(coroutine.create(function() 
	while true do
		repeat task.wait(1) round.Waiting(#Players:GetPlayers(), minimumPlayers) until #Players:GetPlayers() >= minimumPlayers

		round.Intermission(intermissionTime)
		
		round.StartRound(gameLength)

		task.wait(3)
	end
end))

Time bomb script (tool):

local Players = game:GetService("Players")
local serverStorage = game:GetService("ServerStorage")
local prefabs = serverStorage:WaitForChild("MainGame"):WaitForChild("Prefabs")

local tool = script.Parent
local event = tool:WaitForChild("Event")

local cooldown = false
local cooldownTime = 15

local character

tool.Equipped:Connect(function()
	character = tool.Parent
end)

tool.Activated:Connect(function()
	if not cooldown then
		if character then
			local bombClone = prefabs:FindFirstChild(tool.Name):Clone()
			bombClone.Parent = workspace
			bombClone.PrimaryPart.CFrame = tool:WaitForChild("Handle").CFrame
			
			if bombClone:FindFirstChild("WeaponScript") and bombClone:FindFirstChild("WeaponScript"):IsA("Script") then
				bombClone:FindFirstChild("WeaponScript").Enabled = true
			end
			
			cooldown = true
			event:FireClient(Players:GetPlayerFromCharacter(character), "Reloading")
			
			task.wait(cooldownTime)
			
			event:FireClient(Players:GetPlayerFromCharacter(character), "Reloaded")
			cooldown = false
		end
	end
end)

Time bomb script (prefab):

local bomb = script.Parent
local tickSound = bomb:WaitForChild("Tick")
local explosionSound = bomb:WaitForChild("Explosion")

local updateInterval = 0.8

local function updateTime()
	tickSound:Play()
	updateInterval *= 0.9
end

local function blowUp()
	local explosion = Instance.new("Explosion")
	explosion.Parent = workspace
	explosion.BlastRadius = 20
	explosion.BlastPressure = 1000000
	explosion.Position = bomb.Base.Position
	
	bomb.String.Transparency = 1
	bomb.Base.Transparency = 1
	bomb.Top.Transparency = 1
	
	explosionSound:Play()
end

while updateInterval > 0.1 do
	task.wait(updateInterval)
	updateTime()
end

blowUp()
task.wait(3)
bomb:Destroy()

Any help is greatly appreciated! Thank you!

Best regards,
Amora.

1 Like

Try using PivotTo instead of .PrimaryPart.CFrame.

This still did not work unfortunately.

It works the same as before. It does clone it successfully and literally everything else changes, it’s just the position doesn’t get set. It stays at 0, 0, 0 (the position of the prefab in the workspace).

Is it possible that it’s welded to something?

The only things in the prefab with welds are the parts of the bomb to themselves.


Here are videos by the way. Forgot to add these in the original post:

The only difference between these two videos is the fact that the tool was cloned into the players backpack


Also here’s a video of me cloning it to my backpack manually. It works just fine doing it by hand. I don’t understand why it does this only when it’s cloned via the script. It does this with projectile tools in one of my other games as well.

It might be because you are enabling the scripts with this code. This isn’t necessary when the tool is in server storage, because scripts do not run there with the legacy RunContext.

It might also be because you are parenting the tool before doing modifications to the scripts (this is the case with all instances). I don’t recommend this because of performance reasons but also because of the scripts running as soon as you enable them.

It might also be because of this:

I recommend cloning each tool inside the pack instead of cloning the whole pack. However, I’m unsure if this will make a difference.

1 Like

I don’t think it’s because of this since that was something I tried to resolve the issue. It is also necessary in my case with this game since the script uses Legacy run context and is in ReplicatedStorage. And also in my other game, the tools with projectiles have all of their scripts enabled (but are in ServerStorage instead of ReplicatedStorage like in this game).


I’ll try doing everything before it is parented. It is literally only the tool and not the prefab in ServerStorage. It’s so confusing to me.

Okay so I made it so when unpacking the weapons from the folder, the folder is not parented. I also parented the tool after making the script enabled. No change at all

I also made the tool’s script run context Script instead of Legacy. Also no change at all.


I’m going to try to change the bomb’s position in the prefab’s script instead of the tool’s script. That might fix it. I’m unsure. And if it does, that doesn’t solve the same issue with projectiles in my other game. I’ll worry about that when I actually start working on that game, though.

So setting the cloned bomb’s position before parenting it didn’t work; however, creating a bindable event and using that to set the position in the bomb prefab’s script did NOT work. The idea was when that gets fired by the tool’s script, the prefab’s script picks it up and sets the position there instead of through the tool script, but that didn’t work either. I’m very confused.

I’m very confused as well. Is the bomb clone anchored? If not, try calling bombClone:BreakJoints(). It should at least partially work at that point, but the bomb will fall apart.

Are you sure the primary part of the bomb is considered the AssemblyRootPart? If not, try increasing the root priority or make the other parts massless.

The bomb clone is not anchored. I would try BreakJoints, but I don’t want it falling apart, obviously.


And yes, the primary part IS the AssemblyRootPart; however, I’ll give making the parts massless a try.

Clone the handle of the bomb tool, maybe this will work? I seen this with roblox tools such as the bomb tool.

1 Like

With my current code setup, how would I go about this? The way my game is currently setup, there are multiple tools with projectiles (including the time bomb. Though not a projectile, it has the same issue as the tools that fire projectiles), but there are also tools that don’t have any kind of cloning at all. All of the code is within the tool itself (i.e. no prefabs in ServerStorage). I would assume cloning the handle of every tool in the player’s backpack would cause some sort of error at some point.

Okay. I set it up to do so, but as I predicted, it didn’t work. I’m am so confused lol

I still need help with this issue! There was one time that it actually worked properly, but the round after that it stopped working again. I don’t know why it only worked one time out of thousands of tested rounds, but my issue with the tool still persists.

I have attached videos in post #5

I also just tried the solution in post #12 and it did NOT work.


It’s urgent I get this fixed by at least the end of February because that’s when I plan to release the first public build of the game. If I can’t get this fixed by then, it’s okay. I can leave it out until I do get it fixed.

New issue as well. Now the cloned bomb gets destroyed after about a second but only sometimes. I think it might be because of it rolling of the map. I’m not sure because it always spawns on the edge of the baseplate
Now I have to figure this out as well :sob:

Okay, so I did get it fixed but not by my own means.

This time bomb was completely custom, but I had to swallow my pride and use the classic roblox time bomb instead.

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