Unit Limit Bug | Roblox Tower Defense |

The limit system seams to be working but when I upgrade a unit I can add another onee. As you can see here:

When I upgrade:

function UnitSpawnModule.Spawn(player, name, cframe, previous)
	local AllowedToSpawn = UnitSpawnModule.CheckSpawn(player, name)
	local Count = 0
	
	local modelName = name
	local newName = string.gsub(modelName, "%[%d+%]", "")
	
	
	for i,v in pairs(workspace.Units:GetChildren()) do
		if v.Name == name and not v:HasTag("IsUpgrade") then
			Count+=1
		end
	end


	if ReplicatedStorage.Units[newName].Config.Limit then
		if Count >= ReplicatedStorage.Units[newName].Config.Limit.Value then
			AllowedToSpawn = false -- Limit reached
		end
	else
		warn(name.."has no spawn limit")
	end

	
	
	if AllowedToSpawn and Debounce == false then
		if Debounce then return end
		Debounce = true
		local newUnit
		
		if previous then
			previous:Destroy()
			newUnit = ReplicatedStorage.Units.Upgrades:FindFirstChild(name, true):Clone()
			newUnit:AddTag("IsUpgrade")
		else
		    newUnit = ReplicatedStorage.Units[name]:Clone()
		end
		
		
		
		
		
		
		newUnit:WaitForChild("HumanoidRootPart").CFrame = cframe
		newUnit.Parent = workspace.Units
		local bodyGyro = Instance.new("BodyGyro")
		bodyGyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
		bodyGyro.D = 0
		bodyGyro.CFrame = newUnit.HumanoidRootPart.CFrame
		bodyGyro.Parent = newUnit.HumanoidRootPart

		
		
	
		
			newUnit.HumanoidRootPart:SetNetworkOwner(nil)
			--local humPart = newUnit:WaitForChild("HumanoidRootPart")


			
			player.Money.Value -= newUnit.Config.Cost.Value
			
		local cloneSound = gameSFXFolder.Coins.CoinPlace:Clone()
		local attachment = Instance.new("Attachment")
		attachment.Name = "PlaceSound"
		attachment.Parent = newUnit.HumanoidRootPart
		cloneSound.Parent = attachment
		cloneSound:Play()

		MoneyGoneEvent:FireClient(player, newUnit.Config.Cost.Value)
		Debounce = false


			coroutine.wrap(UnitSpawnModule.Attack)(newUnit, player)
			
			return newUnit 
			

	
		
	else
		warn("Requested Unit does not exist: "..name)
		return false
	end
end

This is the code…

This is the config folder inside the Unit…

1 Like

I think you should do the newName when you know it is an upgrade.

Can I ask How would youu do thatt?

Hello! You should check player placed same units counting instead of checking up the units name :smiley:

Something like this:

function UnitSpawnModule.Spawn(player, name, cframe, previous)
	local AllowedToSpawn = UnitSpawnModule.CheckSpawn(player, name)
	local Count = 0
	
	local modelName = name
	local newName = modelName

	if v:HasTag("IsUpgrade") then
		newName = string.gsub(modelName, "%[%d+%]", "")
	end
	
	
	for i,v in pairs(workspace.Units:GetChildren()) do
		if v.Name == name and not v:HasTag("IsUpgrade") then
			Count+=1
		end
	end


	if ReplicatedStorage.Units[newName].Config.Limit then
		if Count >= ReplicatedStorage.Units[newName].Config.Limit.Value then
			AllowedToSpawn = false -- Limit reached
		end
	else
		warn(name.."has no spawn limit")
	end

	
	
	if AllowedToSpawn and Debounce == false then
		if Debounce then return end
		Debounce = true
		local newUnit
		
		if previous then
			previous:Destroy()
			newUnit = ReplicatedStorage.Units.Upgrades:FindFirstChild(name, true):Clone()
			newUnit:AddTag("IsUpgrade")
		else
		    newUnit = ReplicatedStorage.Units[name]:Clone()
		end
		
		
		
		
		
		
		newUnit:WaitForChild("HumanoidRootPart").CFrame = cframe
		newUnit.Parent = workspace.Units
		local bodyGyro = Instance.new("BodyGyro")
		bodyGyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
		bodyGyro.D = 0
		bodyGyro.CFrame = newUnit.HumanoidRootPart.CFrame
		bodyGyro.Parent = newUnit.HumanoidRootPart

		
		
	
		
			newUnit.HumanoidRootPart:SetNetworkOwner(nil)
			--local humPart = newUnit:WaitForChild("HumanoidRootPart")


			
			player.Money.Value -= newUnit.Config.Cost.Value
			
		local cloneSound = gameSFXFolder.Coins.CoinPlace:Clone()
		local attachment = Instance.new("Attachment")
		attachment.Name = "PlaceSound"
		attachment.Parent = newUnit.HumanoidRootPart
		cloneSound.Parent = attachment
		cloneSound:Play()

		MoneyGoneEvent:FireClient(player, newUnit.Config.Cost.Value)
		Debounce = false


			coroutine.wrap(UnitSpawnModule.Attack)(newUnit, player)
			
			return newUnit 
			

	
		
	else
		warn("Requested Unit does not exist: "..name)
		return false
	end
end
1 Like

image

This error Appearss

Heyy mann How would you go about doing that If I could ask??

You should make a player unit handler so when a player place a unit here what you do:

Player place Blabla Tower then:

  • workspace.PlayerTowers(Folder) and create a folder of the player userId so player.UserId and you add towers inside this folder
  • add a checker of how many towers this player have and check up with your limits

Okay how would I implement that in the module

image

This Units folder is where all the units get stored

My bad i forgot that v is not defined, try this:

function UnitSpawnModule.Spawn(player, name, cframe, previous)
	local AllowedToSpawn = UnitSpawnModule.CheckSpawn(player, name)
	local Count = 0
	
	local modelName = name
	local newName = modelName
	
	
	for i,v in pairs(workspace.Units:GetChildren()) do
		if v.Name == name then
		  if not v:HasTag("IsUpgrade") then
		    Count+=1
		    else
		      newName = string.gsub(modelName, "%[%d+%]", "")
		    end
		end
	end


	if ReplicatedStorage.Units[newName].Config.Limit then
		if Count >= ReplicatedStorage.Units[newName].Config.Limit.Value then
			AllowedToSpawn = false -- Limit reached
		end
	else
		warn(name.."has no spawn limit")
	end

	
	
	if AllowedToSpawn and Debounce == false then
		if Debounce then return end
		Debounce = true
		local newUnit
		
		if previous then
			previous:Destroy()
			newUnit = ReplicatedStorage.Units.Upgrades:FindFirstChild(name, true):Clone()
			newUnit:AddTag("IsUpgrade")
		else
		    newUnit = ReplicatedStorage.Units[name]:Clone()
		end
		
		
		
		
		
		
		newUnit:WaitForChild("HumanoidRootPart").CFrame = cframe
		newUnit.Parent = workspace.Units
		local bodyGyro = Instance.new("BodyGyro")
		bodyGyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
		bodyGyro.D = 0
		bodyGyro.CFrame = newUnit.HumanoidRootPart.CFrame
		bodyGyro.Parent = newUnit.HumanoidRootPart

		
		
	
		
			newUnit.HumanoidRootPart:SetNetworkOwner(nil)
			--local humPart = newUnit:WaitForChild("HumanoidRootPart")


			
			player.Money.Value -= newUnit.Config.Cost.Value
			
		local cloneSound = gameSFXFolder.Coins.CoinPlace:Clone()
		local attachment = Instance.new("Attachment")
		attachment.Name = "PlaceSound"
		attachment.Parent = newUnit.HumanoidRootPart
		cloneSound.Parent = attachment
		cloneSound:Play()

		MoneyGoneEvent:FireClient(player, newUnit.Config.Cost.Value)
		Debounce = false


			coroutine.wrap(UnitSpawnModule.Attack)(newUnit, player)
			
			return newUnit 
			

	
		
	else
		warn("Requested Unit does not exist: "..name)
		return false
	end
end

image

This Error Again 0.0

This happens because the loop happens before setting the Tags, so everything does not have a tag for the script.

Shouldd I just add the tags manuallyy?? will that work

You do not need to add manually, you can try checking before looping:

function UnitSpawnModule.Spawn(player, name, cframe, previous)
	local AllowedToSpawn = UnitSpawnModule.CheckSpawn(player, name)
	local Count = 0
	
	local modelName = name
	local newName = modelName

	if AllowedToSpawn and Debounce == false then
		if Debounce then return end
		Debounce = true
		local newUnit
		
		if previous then
			previous:Destroy()
			newUnit = ReplicatedStorage.Units.Upgrades:FindFirstChild(name, true):Clone()
			newUnit:AddTag("IsUpgrade")
		else
		    newUnit = ReplicatedStorage.Units[name]:Clone()
		end
	
	
	for i,v in pairs(workspace.Units:GetChildren()) do
		if v.Name == name then
		  if not v:HasTag("IsUpgrade") then
		    Count+=1
		    else
		      newName = string.gsub(modelName, "%[%d+%]", "")
		    end
		end
	end


	if ReplicatedStorage.Units[newName].Config.Limit then
		if Count >= ReplicatedStorage.Units[newName].Config.Limit.Value then
			AllowedToSpawn = false -- Limit reached
		end
	else
		warn(name.."has no spawn limit")
	end
		
		
		
		
		
		
		newUnit:WaitForChild("HumanoidRootPart").CFrame = cframe
		newUnit.Parent = workspace.Units
		local bodyGyro = Instance.new("BodyGyro")
		bodyGyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
		bodyGyro.D = 0
		bodyGyro.CFrame = newUnit.HumanoidRootPart.CFrame
		bodyGyro.Parent = newUnit.HumanoidRootPart

		
		
	
		
			newUnit.HumanoidRootPart:SetNetworkOwner(nil)
			--local humPart = newUnit:WaitForChild("HumanoidRootPart")


			
			player.Money.Value -= newUnit.Config.Cost.Value
			
		local cloneSound = gameSFXFolder.Coins.CoinPlace:Clone()
		local attachment = Instance.new("Attachment")
		attachment.Name = "PlaceSound"
		attachment.Parent = newUnit.HumanoidRootPart
		cloneSound.Parent = attachment
		cloneSound:Play()

		MoneyGoneEvent:FireClient(player, newUnit.Config.Cost.Value)
		Debounce = false


			coroutine.wrap(UnitSpawnModule.Attack)(newUnit, player)
			
			return newUnit 
			

	
		
	else
		warn("Requested Unit does not exist: "..name)
		return false
	end
end


The Limit stops working and this warning appears

function UnitSpawnModule.Spawn(player, name, cframe, previous)
	local AllowedToSpawn = UnitSpawnModule.CheckSpawn(player, name)
	local Count = 0

	local modelName = name
	local newName = modelName



	


	if AllowedToSpawn and Debounce == false then
		if Debounce then return end
		Debounce = true
		local newUnit

		if previous then
			previous:Destroy()
			newUnit = ReplicatedStorage.Units.Upgrades:FindFirstChild(name, true):Clone()
			newUnit:AddTag("IsUpgrade")
		else
			newUnit = ReplicatedStorage.Units[name]:Clone()
		end
		
		
		for i,v in pairs(workspace.Units:GetChildren()) do
			if v.Name == name then
				if not v:HasTag("IsUpgrade") then
					Count+=1
				else
					newName = string.gsub(modelName, "%[%d+%]", "")
				end
			end
		end


		if ReplicatedStorage.Units[newName].Config.Limit then
			if Count >= ReplicatedStorage.Units[newName].Config.Limit.Value then
				AllowedToSpawn = false -- Limit reached
			end
		else
			warn(name.."has no spawn limit")
		end




		newUnit:WaitForChild("HumanoidRootPart").CFrame = cframe
		newUnit.Parent = workspace.Units
		local bodyGyro = Instance.new("BodyGyro")
		bodyGyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
		bodyGyro.D = 0
		bodyGyro.CFrame = newUnit.HumanoidRootPart.CFrame
		bodyGyro.Parent = newUnit.HumanoidRootPart





		newUnit.HumanoidRootPart:SetNetworkOwner(nil)
		--local humPart = newUnit:WaitForChild("HumanoidRootPart")



		player.Money.Value -= newUnit.Config.Cost.Value

		local cloneSound = gameSFXFolder.Coins.CoinPlace:Clone()
		local attachment = Instance.new("Attachment")
		attachment.Name = "PlaceSound"
		attachment.Parent = newUnit.HumanoidRootPart
		cloneSound.Parent = attachment
		cloneSound:Play()

		MoneyGoneEvent:FireClient(player, newUnit.Config.Cost.Value)
		Debounce = false


		coroutine.wrap(UnitSpawnModule.Attack)(newUnit, player)

		return newUnit 




	else
		warn("Requested Unit does not exist: "..name)
		return false
	end
end



Also as what i see you don’t manage player towers since every tower are stored in Units folder under workspace, imagine if there like 5 players placing same units they will be limiteds aswell same if they place only one or none?

1 Like

Ohh yeahh you’re rightt about thatt

As what i said above make a folder for each players under your Units folder with their userId so you can easily manage players towers and their respective limits :smiley:

1 Like

Alright man I’ll work on thatt

1 Like

Okay so this happens because you clean the name and then the script later looks for Fein[1], thinking it still exists.

function UnitSpawnModule.Spawn(player, name, cframe, previous)
	local AllowedToSpawn = UnitSpawnModule.CheckSpawn(player, name)
	local Count = 0

	local modelName = name
	local newName = modelName

	if AllowedToSpawn and Debounce == false then
		if Debounce then return end
		Debounce = true
		local newUnit

		if previous then
			previous:Destroy()
			newUnit = ReplicatedStorage.Units.Upgrades:FindFirstChild(name, true):Clone()
			newUnit:AddTag("IsUpgrade")
		else
			newUnit = ReplicatedStorage.Units[name]:Clone()
		end
		
		for i,v in pairs(workspace.Units:GetChildren()) do
			if v.Name == name then
				if not v:HasTag("IsUpgrade") then
					Count += 1
				else
					newName = string.gsub(modelName, "%[%d+%]", "")
				end
			end
		end

		if ReplicatedStorage.Units:FindFirstChild(newName) and not ReplicatedStorage.Units:FindFirstChild(newName):HasTag("IsUpgrade") then
			if ReplicatedStorage.Units[newName].Config.Limit then
				if Count >= ReplicatedStorage.Units[newName].Config.Limit.Value then
					AllowedToSpawn = false
				end
			else
				warn(name.."has no spawn limit")
			end
		else
			warn("Unit does not exist: "..newName)
			return false
		end

		newUnit:WaitForChild("HumanoidRootPart").CFrame = cframe
		newUnit.Parent = workspace.Units
		local bodyGyro = Instance.new("BodyGyro")
		bodyGyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
		bodyGyro.D = 0
		bodyGyro.CFrame = newUnit.HumanoidRootPart.CFrame
		bodyGyro.Parent = newUnit.HumanoidRootPart

		newUnit.HumanoidRootPart:SetNetworkOwner(nil)
		--local humPart = newUnit:WaitForChild("HumanoidRootPart")

		player.Money.Value -= newUnit.Config.Cost.Value

		local cloneSound = gameSFXFolder.Coins.CoinPlace:Clone()
		local attachment = Instance.new("Attachment")
		attachment.Name = "PlaceSound"
		attachment.Parent = newUnit.HumanoidRootPart
		cloneSound.Parent = attachment
		cloneSound:Play()

		MoneyGoneEvent:FireClient(player, newUnit.Config.Cost.Value)
		Debounce = false

		coroutine.wrap(UnitSpawnModule.Attack)(newUnit, player)

		return newUnit
	else
		warn("Requested Unit does not exist: "..name)
		return false
	end
end