I made a building system that only works with parts and its pretty reliable. But the thing is, I don't know how to make it build models, I've thought of :MoveTo but obviously it wont be as smooth or it won't work at all.
Heres my script.
LocalScript:
--// Variables \\--
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlaceStructure = ReplicatedStorage.Events:WaitForChild("PlaceStructure")
local Structures = ReplicatedStorage:WaitForChild("Structures")
local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local player = game.Players.LocalPlayer
local structureFrame = script.Parent.Build
local PlayerMenu = script.Parent
local char = player.Character or player.Character:Wait()
local HumanoidRootPart = char:WaitForChild("HumanoidRootPart")
local cancelLabel = script.Parent.Parent.CancelLabel
local rotateLabel = script.Parent.Parent.RotateLabel
local mouse = player:GetMouse()
local yBuildingOffset = 5
local maxPlacingDistance = 5
local rKeyIsPressed = false
local PlacingStructure = false
--// Main \\--
for _, structure in pairs(structureFrame:GetChildren()) do
if structure:IsA("Frame") then
for _, structureButton in pairs(structure:GetChildren()) do
if structureButton:IsA("TextButton") then
for _, ingr1 in pairs(structure:GetChildren()) do
if ingr1.Name == "Ingr1" then
for _, ingr2 in pairs(structure:GetChildren()) do
if ingr2.Name == "Ingr2" then
if player.PlayerStats[ingr1.Value].Value >= ingr1.Amount.Value and player.PlayerStats[ingr2.Value].Value >= ingr2.Amount.Value then
structureButton.MouseButton1Up:Connect(function()
PlayerMenu.Visible = false
cancelLabel.Visible = true
rotateLabel.Visible = true
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("Cyan")
clientStructure.Material = "Wood"
clientStructure.CanCollide = false
clientStructure.Transparency = 0.5
clientStructure.Anchored = true
clientStructure.Parent = workspace
local startingCFrame = CFrame.new(0, -2, -15)
clientStructure.CFrame = HumanoidRootPart.CFrame:ToWorldSpace(startingCFrame)
UIS.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.C then
PlacingStructure = false
cancelLabel.Visible = false
rotateLabel.Visible = false
clientStructure:Destroy()
print("cancelled")
end
end)
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 (hit:IsA("Terrain")) or hit.Name:lower() == "terrain" and (clientStructure.Position - HumanoidRootPart.Position).Magnitude < maxPlacingDistance then
goodToPlace = true
clientStructure.BrickColor = BrickColor.new("Cyan")
else
goodToPlace = false
clientStructure.BrickColor = BrickColor.new("Bright red")
end
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
cancelLabel.Visible = false
rotateLabel.Visible = false
clientStructure:Destroy()
end
end
end
end
end)
end
end)
else
warn("Not Enough Materials!")
end
end
end
end
end
end
end
end
end
Server Script:
Rep.Events.PlaceStructure.OnServerInvoke = function(player, StructureName, StructureCFrame)
local random
local realStructure = Structures:FindFirstChild(StructureName):Clone()
if realStructure then
realStructure.CFrame = StructureCFrame
realStructure.Parent = workspace
random = true
else
random = false
end
return random
end

1 comment
I don't think looping through a model