Why won't my tower place?

I have a script for my tower defense game that places a tower. The tower movement is fine, it just doesn’t actually place

						UIS.InputBegan:Connect(function(input)
							if input.UserInputType == Enum.UserInputType.MouseButton1 then
								if placingTower == true then
									if goodToPlace == true then
										local TowerCFrame = clientTower.CFrame
										placedTower = PlaceTower:InvokeServer(clientTower.Name, TowerCFrame)
										
										if placedTower == true then
											placingTower = false
											clientTower:Destroy()
											TowerFrame.Visible = true
										end
									end
								end
							end
						end)
					end
				end)
			end
		end)
	end
end

This is another script to fire the place event in replicated storage

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlaceTower = ReplicatedStorage:WaitForChild("PlaceTower")
local Towers = ReplicatedStorage:WaitForChild("Towers")

PlaceTower.OnServerInvoke = function(player, TowerName, TowerCFrame)
	
	local crafted
	local realTower = Towers:FindFirstChild(TowerName):Clone()
	
	if realTower then
		realTower.HumanoidRootPart.CFrame = TowerCFrame
		realTower.Parent = game.Workspace.Towers
		crafted = true
	else
		crafted = false
	end
	
	return crafted
end

–Cleint Script–

UIS.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		if placingTower and goodToPlace then

			local TowerCFrame = clientTower.CFrame
			placedTower = PlaceTower:InvokeServer(clientTower.Name, TowerCFrame)

			if placedTower then
				placingTower = false
				clientTower:Destroy()
				TowerFrame.Visible = true
			end

		end
	end
end)

–place event script –

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlaceTower = ReplicatedStorage:WaitForChild("PlaceTower")
local Towers = ReplicatedStorage:WaitForChild("Towers")

PlaceTower.OnServerInvoke = function(player, TowerName, TowerCFrame)

	local crafted
	local realTower = Towers:FindFirstChild(TowerName):Clone()

	if realTower then
		realTower.PrimaryPart.CFrame = CFrame.new(TowerCFrame)
		realTower.Parent = game.Workspace.Towers
		crafted = true
	else
		crafted = false
	end

	return crafted
end

this could be

	local realTower = Towers:FindFirstChild(TowerName):Clone()

	if realTower then
		realTower.PrimaryPart.CFrame = CFrame.new(TowerCFrame)
		realTower.Parent = game.Workspace.Towers
	end

	return realTower ~= nil
1 Like

:grinning: nice one I don’t know how I didn’t notice its

1 Like

It still doesn’t place. Also, the place event script is a normal script while the client script is a localscript.

Are you certain it’s not placing? Check the Towers folder and see if anything gets added.

I have a few theories why it could be the case, although I dont know if you’re erroring to begin with.

  • Maybe try using SetPrimaryPartCFrame instead of PrimaryPart.CFrame?
  • TowerCFrame is already a CFrame, no need to use CFrame.new, just give it TowerCFrame
realTower:SetPrimaryPartCFrame(TowerCFrame)
  • Does the Client code reach the InvokeServer to begin with? Add print statements to see where it stops

Also, your server code can simplified even further

PlaceTower.OnServerInvoke = function(player, TowerName, TowerCFrame)
	local realTower = Towers[TowerName]:Clone()

	realTower:SetPrimaryPartCFrame(TowerCFrame)
	realTower.Parent = game.Workspace.Towers

	return true
end

Because if the FindFirstChild fails you’ll just get an Attempt to index nil with Clone, so no point in checking if realTower exists or not in that case

1 Like

I tried using a print statement in the client script. I put it under the server invoked part and it didn’t print meaning it didn’t even get to that part.

UIS.InputBegan:Connect(function(input)
							if input.UserInputType == Enum.UserInputType.MouseButton1 then
								if placingTower and goodToPlace then
									
									local TowerCFrame = clientTower.CFrame
									placedTower = placingTower:InvokeServer(clientTower.Name, TowerCFrame)
									print("Server Invoked")
									
									if placedTower then
										placingTower = false
										clientTower:Destroy()
										TowerFrame.Visible = true

Also, the tower goes in the Towers folder in workspace.

Nothing wrong in the output either.

I can give the full client script if needed.

Put prints before any of the code in InputBegan to print placingTower, goodToPlace, and the UserInputType, could be that it’s not even passing the if statements.

Having the full client script should give some more info if needed here

I’ll be able to show you once I get on my pc. Won’t be for a bit though.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlaceTower = ReplicatedStorage:WaitForChild("PlaceTower")
local Tower = ReplicatedStorage.Towers.Minigunner
local Towers = ReplicatedStorage:WaitForChild("Towers")

local UIS = game:GetService("UserInputService")

local player = game.Players.LocalPlayer
local Character = player.Character or player.Character:Wait()

local Mouse = player:GetMouse()
local placingTower = false
local TowerFrame = script.Parent.TowerFrame

for _, towerButton in pairs(TowerFrame:GetChildren()) do
	if towerButton:IsA("TextButton") then
		towerButton.MouseButton1Up:Connect(function()

			TowerFrame.Visible = false

			local goodToPlace = false
			local placedTower

			if placingTower == false then
				placingTower = true

				local clientTower = Towers:FindFirstChild(towerButton.Name):Clone()
				clientTower.Hitbox.SelectionBox.Color3 = Color3.new(0.154482, 0.739025, 0.102632)
				clientTower.Parent = game.Workspace.Towers

				Mouse.TargetFilter = clientTower
				game:GetService("RunService").RenderStepped:Connect(function()
					if Mouse.Target ~= nil then
						clientTower.PrimaryPart.CFrame = CFrame.new(Mouse.Hit.Position) * CFrame.new(0, clientTower.Hitbox.Size.Y/1.5, 0) -- Offset
						
						UIS.InputBegan:Connect(function(input)
							if input.UserInputType == Enum.UserInputType.MouseButton1 then
								if placingTower and goodToPlace then
									
									local TowerCFrame = clientTower.CFrame
									placedTower = placingTower:InvokeServer(clientTower.Name, TowerCFrame)
									print("Server Invoked")
									
									if placedTower then
										placingTower = false
										clientTower:Destroy()
										TowerFrame.Visible = true
									end
								end
							end
						end)
					end
				end)
			end
		end)
	end
end

If Towers:FindFirstChild(TowerName) returns nil then the :Clone() will throw an error

MY EYES. Should be workspace.Towers as that is a bit faster (won’t really make too much of a difference though)

This could be outside of the renderstepped connection


Could you add a print on the first line of the OnServerInvoke and show me the output?


You could do:

realtower:SetPrimaryPartCFrame(TowerCFrame)

I thought of a big thing:

There could be a typo or a missing folder, causing the server script to yield infinitly

This isn’t really part of your question but I got this error.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlaceTower = ReplicatedStorage.Towers
local Towers = ReplicatedStorage.Towers

PlaceTower.OnServerInvoke = function(player, TowerName, TowerCFrame)
	local realTower = Towers[TowerName]:Clone()
	realTower.SetPrimaryPartCFrame(TowerCFrame)
	realTower.Parent = game.Workspace.Towers

	return true
end

OnServerInvoke is not a valid member of Folder "ReplicatedStorage.Towers"
line 5

Also, I put a print here

									print("Server Invoke Test")
									local TowerCFrame = clientTower.CFrame
									placedTower = placingTower:InvokeServer(clientTower.Name, TowerCFrame)

It didn’t print.

Okay in order to fix this you need to change this:

to:

local PlaceTower = ReplicatedStorage.PlaceTower or ReplicatedStorage:WaitForChild("PlaceTower") 

Basically you had the PlaceTower variable set to be the towers folder

I fixed that, but do you have any idea why it didn’t print in my other reply?

It didn’t print because the error stopped the script from running.

It still doesn’t print even though I fixed it.

Try pressing the following buttons on both the client and server scripts in order to ensure they are properly formatted:
CTRL+A(or CMD+A for apple)
CTRL+ALT+SHIFT+F (CMD+ALT+SHIFT+F for apple)

Didn’t change anything. Was it supposed to do anything?

1 Like