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
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
local realTower = Towers:FindFirstChild(TowerName):Clone()
if realTower then
realTower.PrimaryPart.CFrame = CFrame.new(TowerCFrame)
realTower.Parent = game.Workspace.Towers
end
return realTower ~= nil
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
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
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
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
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)