How to make a td place system

so i have a place script but its super buggy i want like when button pressed, the towerplacement tower goes wherver mouse target is but not its pivot but like its surface idk if u get it, and idk why whenever i fire server it doesnt move to where it is:

local:

local button = script.Parent
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local repStorage = game.ReplicatedStorage
local towersFolder = repStorage:WaitForChild("TowerPlacement")
local towerClone = nil
local isCloning = false
local gridSize = 5

local function getGridPosition(position)
	local gridPosition = Vector3.new(
		math.floor(position.X / gridSize + 0.5) * gridSize,
		position.Y,
		math.floor(position.Z / gridSize + 0.5) * gridSize
	)
	return gridPosition
end

button.MouseButton1Click:Connect(function()
	if isCloning then
		isCloning = false
		if towerClone then
			towerClone:Destroy()
		end
	else
		isCloning = true
		if towerClone then
			towerClone:Destroy()
		end

		local towerTemplate = towersFolder:FindFirstChild("Tower")
		if towerTemplate then
			towerClone = towerTemplate:Clone()
			towerClone.Parent = workspace

			for _, part in ipairs(towerClone:GetDescendants()) do
				if part:IsA("BasePart") then
					part.Anchored = true
					part.CanCollide = false
				end
			end
		end
	end
end)

game:GetService("RunService").Heartbeat:Connect(function()
	if isCloning and towerClone then
		local targetPart = mouse.Target
		if targetPart and targetPart:IsA("BasePart") then
			local gridPosition = getGridPosition(targetPart.Position)
			towerClone:SetPrimaryPartCFrame(CFrame.new(gridPosition + Vector3.new(0, 3, 0)))
		end
	end
end)

mouse.Button1Down:Connect(function()
	if towerClone then
		local targetPart = mouse.Target
		if targetPart and targetPart:IsA("BasePart") then
			local gridPosition = getGridPosition(targetPart.Position)
			repStorage:WaitForChild("TowerPlacement"):FireServer(gridPosition + Vector3.new(0, 3, 0))
		end
		towerClone:Destroy()
		towerClone = nil
		isCloning = false
	end
end)

server:

local repStorage = game.ReplicatedStorage
local towersFolder = repStorage:WaitForChild(“Towers”)

repStorage:WaitForChild(“TowerPlacement”).OnServerEvent:Connect(function(player, position)
local towerTemplate = towersFolder:FindFirstChild(“Tower”)
if towerTemplate then
local newTower = towerTemplate:Clone()
newTower.Parent = workspace
newTower.HumanoidRootPart.Position = position

	for _, part in ipairs(newTower:GetDescendants()) do
		if part:IsA("BasePart") then
			part.Anchored = true
			part.CanCollide = true
		end
	end
end

end)

The target part’s position is different from the mouse’s 3D position. Use Mouse.Hit.Position

1 Like

ok rn its this: (local)

local button = script.Parent
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local repStorage = game.ReplicatedStorage
local towersFolder = repStorage:WaitForChild("TowerPlace")
local towerClone = nil
local isCloning = false
local gridSize = 1

local function getGridPosition(position)
	local gridPosition = Vector3.new(
		math.floor(position.X / gridSize + 0.5) * gridSize,
		position.Y,
		math.floor(position.Z / gridSize + 0.5) * gridSize
	)
	return gridPosition
end

button.MouseButton1Click:Connect(function()
	if isCloning then
		isCloning = false
		if towerClone then
			towerClone:Destroy()
		end
	else
		isCloning = true
		if towerClone then
			towerClone:Destroy()
		end

		local towerTemplate = towersFolder:FindFirstChild("Tower")
		if towerTemplate then
			towerClone = towerTemplate:Clone()
			towerClone.Parent = workspace

			for _, part in ipairs(towerClone:GetDescendants()) do
				if part:IsA("BasePart") then
					part.Anchored = true
					part.CanCollide = false
				end
			end
		end
	end
end)

game:GetService("RunService").Heartbeat:Connect(function()
	if isCloning and towerClone then
		local position = mouse.Hit.Position
		local gridPosition = getGridPosition(position)
		towerClone:SetPrimaryPartCFrame(CFrame.new(gridPosition + Vector3.new(0, 3, 0)))
	end
end)

mouse.Button1Down:Connect(function()
	if towerClone then
		local position = mouse.Hit.Position
		local gridPosition = getGridPosition(position)
		repStorage:WaitForChild("TowerPlacement"):FireServer(gridPosition + Vector3.new(0, 3, 0))
		towerClone:Destroy()
		towerClone = nil
		isCloning = false
	end
end)

its kinda buggy though ur idea worked but still buggy

nvm i fixed it but ur tip helped a lot

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