So i got this code that when u click a UI button it will allow u to place an object, in this case just a simple brick for testing.
The problem im having right now is that when im placing it for the first time it works fine, but after the times i place it after that, it just keeps on cloning.
What i mean by that the first time it places 1 brick, then 2, then 3 and so on. So it seems like it just keeps on cloning the objects on top of each other.
Can anyone find this error in the code, because i really cant find it.
Thanks in advance! (code below)
local player = game.Players.LocalPlayer
local StructureFrame = script.Parent.PlacementFrame
local char = player.Character or player.Character:Wait()
local HumanoidRootPart = char:WaitForChild("HumanoidRootPart")
local mouse = player:GetMouse()
local maxPlacingDistance = 10
local rKeyIsPressed = false
local placingStructure = false
for _, structureButton in pairs(StructureFrame:GetChildren()) do
if structureButton:IsA("TextButton") then
structureButton.MouseButton1Click:Connect(function()
StructureFrame.Visible = false
local yOrientation = 0
local goodToPlace = false
local placedStructure
if placingStructure == false then
placingStructure = true
local clientStructure = Structures:FindFirstChild(structureButton.Name):Clone()
clientStructure.BrickColor = BrickColor.new("Forest green")
clientStructure.Material = "Neon"
clientStructure.CanCollide = false
clientStructure.Parent = game.Workspace
local startingCFrame = CFrame.new(0, -2, -15)
clientStructure.CFrame = HumanoidRootPart.CFrame:ToWorldSpace(startingCFrame)
RunService.RenderStepped:Connect(function()
local mouseRay = mouse.UnitRay
local castRay = Ray.new(mouseRay.Origin, mouseRay.Direction * 1000)
local ignoreList = {clientStructure, char}
local hit, position = workspace:FindPartOnRayWithIgnoreList(castRay, ignoreList)
if hit and (HumanoidRootPart.Position - clientStructure.Position).Magnitude < maxPlacingDistance then
goodToPlace = true
clientStructure.BrickColor = BrickColor.new("Forest green")
else
goodToPlace = false
clientStructure.BrickColor = BrickColor.new("Crimson")
end
local yBuildingOffset = clientStructure.Size.Y / 2
local newAnglesCFrame = CFrame.Angles(0, math.rad(yOrientation), 0)
local newCFrame = CFrame.new(position.X, position.Y + yBuildingOffset, position.Z)
clientStructure.CFrame = newCFrame * newAnglesCFrame
end)
UIS.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.R then
rKeyIsPressed = true
local rotationSpeed = 5
while rKeyIsPressed do
wait()
if placingStructure == true then
yOrientation = yOrientation + rotationSpeed
end
end
end
end)
UIS.InputEnded:Connect(function(input)
if input.KeyCode == Enum.KeyCode.R then
rKeyIsPressed = false
end
end)
UIS.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
if placingStructure == true then
if goodToPlace == true then
local structureCFrame = clientStructure.CFrame
placedStructure = PlaceStructure:InvokeServer(clientStructure.Name, structureCFrame)
if placedStructure == true then
placingStructure = false
clientStructure:Destroy()
StructureFrame.Visible = true
end
end
end
end
end)
end
end)
end
end
make sure the script doesnt get hung back after the first placement, that might be your problem, it getting hung back and cloning
also dont use any loops in the script, or it might not work the second time
if input.UserInputType == Enum.UserInputType.MouseButton1 then
if placingStructure == true then
if goodToPlace == true then
local structureCFrame = clientStructure.CFrame
placedStructure = PlaceStructure:InvokeServer(clientStructure.Name, structureCFrame)
if placedStructure == true then
placingStructure = false
clientStructure:Destroy()
StructureFrame.Visible = true
end
end
end
end
this section of the script can resemble an if then loop, it checks the input type, but the input type can also have a true inside of it, which would make a loop
Try overhauling this part of the script so it doesnt contain any if then statements (if possible) so it cant loop on you
i see it requires a keystroke (and mouseclicks in other areas) to start the loop, but you gotta take into consideration how long an average person will hold down that key for (maybe 2 miliseconds) and make sure when it recieves that key it doesnt start an infinite loop
local player = game.Players.LocalPlayer
local StructureFrame = script.Parent.PlacementFrame
local char = player.Character or player.Character:Wait()
local HumanoidRootPart = char:WaitForChild("HumanoidRootPart")
local mouse = player:GetMouse()
local maxPlacingDistance = 10
local rKeyIsPressed = false
local placingStructure = false
for _, structureButton in pairs(StructureFrame:GetChildren()) do -- possible loop
if structureButton:IsA("TextButton") then
structureButton.MouseButton1Click:Connect(function()
StructureFrame.Visible = false
local yOrientation = 0
local goodToPlace = false
local placedStructure
if placingStructure == false then
placingStructure = true
local clientStructure = Structures:FindFirstChild(structureButton.Name):Clone()
clientStructure.BrickColor = BrickColor.new("Forest green")
clientStructure.Material = "Neon"
clientStructure.CanCollide = false
clientStructure.Parent = game.Workspace
local startingCFrame = CFrame.new(0, -2, -15)
clientStructure.CFrame = HumanoidRootPart.CFrame:ToWorldSpace(startingCFrame)
RunService.RenderStepped:Connect(function()
local mouseRay = mouse.UnitRay
local castRay = Ray.new(mouseRay.Origin, mouseRay.Direction * 1000)
local ignoreList = {clientStructure, char}
local hit, position = workspace:FindPartOnRayWithIgnoreList(castRay, ignoreList)
if hit and (HumanoidRootPart.Position - clientStructure.Position).Magnitude < maxPlacingDistance then
goodToPlace = true
clientStructure.BrickColor = BrickColor.new("Forest green")
else
goodToPlace = false
clientStructure.BrickColor = BrickColor.new("Crimson")
end
local yBuildingOffset = clientStructure.Size.Y / 2
local newAnglesCFrame = CFrame.Angles(0, math.rad(yOrientation), 0)
local newCFrame = CFrame.new(position.X, position.Y + yBuildingOffset, position.Z)
clientStructure.CFrame = newCFrame * newAnglesCFrame
end)
UIS.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.R then -- keystroke if then statement
rKeyIsPressed = true
local rotationSpeed = 5
while rKeyIsPressed do
wait()
if placingStructure == true then
yOrientation = yOrientation + rotationSpeed
end
end
end
end)
UIS.InputEnded:Connect(function(input)
if input.KeyCode == Enum.KeyCode.R then -- keystroke if then statement
rKeyIsPressed = false
end
end)
UIS.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then -- mousebutton if then statement
if placingStructure == true then
if goodToPlace == true then
local structureCFrame = clientStructure.CFrame
placedStructure = PlaceStructure:InvokeServer(clientStructure.Name, structureCFrame)
if placedStructure == true then
placingStructure = false
clientStructure:Destroy()
StructureFrame.Visible = true
end
end
end
end
end)
end
end)
end
end
this is your script above, i found a for do statement on line 13, and that also might be the problem, it recieves children but it never stops recieving children, causing a loop
Im sorry but i dont really get what you are trying to say. I dont think it has to do anything with loops. It just seems like it saves the clone and then clones it again?
when it receives a children, it runs the code, seems simple? but there’s more children in said whatever, so it doesn’t stop receiving children (assuming theres 2 children, it sees the second children, gets that as well, but then goes back to the first one) which results in a loop