Hello! I’ve been looking for a tutorial for how to make a building system, but every single one I find is either a free model or not what I’m looking for. I want a building system similar to this, and I’m not sure how to achieve it. I don’t want an entire script, just an outline on how to achieve this
I also want to be able to make the block not be able to be placed in certain areas.
Anyone have an idea on how to make this?
For the actual building system, you could maybe parent a translucent form of the build model to the character when in build mode, and then use raycasting to figure out the correct y level. I’m not sure how the animating would work since I haven’t ever done anything like it, but the for certain areas, you could use GetPartBoundsInBox() to see if it is overlapping with any off limits areas.
How would I make sure that the object stays in front of the player before placed, and after it is placed that it stays in the position that the reference was at?
You could do something with runService and base it off of the rootPart like this:
local rs = game:GetService("RunService")
local player = game.Players.LocalPlayer
local rootPart = nil
local buildMode = false
local buildModel = -- your model here
player.ChacacterAdded:Connect(function(char)
rootPart = char.HumanoidRootPart
end)
local function BuildUpdate()
if not buildMode the return end
buildModel.PrimaryPart.CFrame = rootPart.CFrame + CFrame.new(10, 0, 0)
end
rs.RenderStepped:Connect(function() BuildUpdate() end)
sorry if this has typos but this should give you the basic idea to go off of for at least the transparent model in front of the player.
What you just saw in that video was … A stored premade model being cloned. Held by the mouse coordinates. It’s background color is white and it’s being displayed with forcefield as the material. When the mouse is clicked (if the model can be set there) the forcefield material is replaced or a new cloned model is swapped in. This is actually the easy part. The hard part is designing a system that can put these objects back in place as they were placed by the player.
local rs = game:GetService("RunService")
local uis = game:GetService("UserInputService")
local player = game.Players.LocalPlayer
local rootPart = nil
local buildModel = workspace:WaitForChild("Part")
local buildModeOn = false
local function DefineRoot(char)
rootPart = char:WaitForChild("HumanoidRootPart")
end
local function InputBegan(input)
if input.KeyCode == Enum.KeyCode.T then
buildModeOn = not buildModeOn
end
end
local function BuildUpdate()
if not buildModeOn then return end
buildModel.CFrame = rootPart:GetPivot() * CFrame.new(0, 0, -10)
buildModel.Position = workspace:Raycast(buildModel.Position, Vector3.new(0, -100, 0)).Position + Vector3.new(0, buildModel.Size.Y / 2, 0)
end
DefineRoot(player.Character)
player.CharacterAdded:Connect(function(char) DefineRoot(char) end)
uis.InputBegan:Connect(function(input) InputBegan(input) end)
rs.RenderStepped:Connect(function() BuildUpdate() end)
This should work but it has some errors still
You can use T to toggle the build system and you should be able to change the buildModel to whatever you want, but I just have it as a part right now. this also doesn’t work if the model is positioned above the player’s rootpart, I am working on that right now.
The cloning system seems pretty basic to me.
The issue I’m having is adjusting the forcefield to stay in front of the character and adjusting the permanent structure to be at the same position as the temporary, however I could either just change the material of the previous one and anchor it, etc.
I mainly just need help keeping the temporary block in front of the player, and it being able to pass through objects, etc.
So many ways to do that … take a look at them links. Have fun!
Myself I would go with a few versions of the model. A light version for the mouse to hold and a real version to be placed down.
How would I change the input local function to a tool.activated function? I don’t use local functions a lot and am sort of in the blank when it comes to them.
local rs = game:GetService("RunService")
local uis = game:GetService("UserInputService")
local player = game.Players.LocalPlayer
local rootPart = nil
local buildModel = workspace:WaitForChild("Part")
local buildModeOn = false
local heightLimit = 10
local heightLowest = -100
local rayCastParams = RaycastParams.new()
rayCastParams.FilterDescendantsInstances = {buildModel}
local function DefineRoot(char)
rootPart = char:WaitForChild("HumanoidRootPart")
end
local function InputBegan(input)
if input.KeyCode == Enum.KeyCode.T then
buildModeOn = not buildModeOn
end
end
local function BuildUpdate()
if not buildModeOn then return end
buildModel.CFrame = rootPart:GetPivot() * CFrame.new(0, 0, -10)
local rayCast = workspace:Raycast(Vector3.new(buildModel.Position.X, buildModel.Position.Y + heightLimit, buildModel.Position.Z), Vector3.new(0, -1 * (heightLimit - heightLowest), 0), rayCastParams)
if rayCast then
buildModel.Position = rayCast.Position + Vector3.new(0, buildModel.Size.Y / 2, 0)
end
end
DefineRoot(player.Character)
player.CharacterAdded:Connect(function(char) DefineRoot(char) end)
uis.InputBegan:Connect(function(input) InputBegan(input) end)
rs.RenderStepped:Connect(function() BuildUpdate() end)
to change it to a tool activated I think you would just change these things:
local function InputBegan(input)
if input.KeyCode == Enum.KeyCode.T then
buildModeOn = not buildModeOn
end
end
uis.InputBegan:Connect(function(input) InputBegan(input) end)
for placeing when the player clicks, do something like this
local function BuildPlace()
local newBuild = buildModel:Clone()
newBuild.CanCollide = true
newBuild.Parent = workspace
end
tool.Activated:Connect(function() BuildPlace() end)
As said here
you can also change the material when the build is placed or instead of cloning the outline part, clone something from replicatedStorage.