How do I make a building system with a grid? (also want to be able to weild + destroy blocks)

Hey all!

So I’m quite new to scripting, and currently im trying to make a build tool where you can place / remove blocks within a certain area, And while I somewhat came up with something I still got quite a few problems

  • I can only build in 3 directions, trying to build on the 3 others sides results in nothing happening.
Trying to build in more than 3 directions

https://gyazo.com/6a899ad87f8dc7bc43f3539e4cef69ed

  • blocks are not weilded so they always fall apaer when building larger structures ( I don’t want to anchor them because they are supposed to fall down when they are destroyed)
  • I got no clue on how to track blocks placed because I’m supposed to be able to remove all the blocks that the players have placed

this is the code I got so far:

-- all of this is in a localscript inside of the hammer tool
local players = game:GetService("Players")
local hammer = script.Parent -- the hammer tool that will make the player know they are in "building mode"
local player = game.Players.LocalPlayer
local mouse = player:GetMouse() -- get the mouse from the player
local redBase = game.Workspace.teamPlatforms.RedTeam.RedTeamPlatform
local baseX = redBase.CFrame.X
local baseY = redBase.CFrame.Y
local baseZ = redBase.CFrame.Z

local width = 300
local height = 300
local size = 5

local function placeBlock(Part)
	
local position = mouse.Hit.p -- the position of the mouse so i can place blocks there
local tempX = math.floor((position.X / size )	+0.5)
local tempY = math.floor((position.Y / size)	+0.5)
local tempZ = math.floor((position.Z / size)	+0.5)

local buildingBrickRed = Instance.new("Part") -- creates a part that the player will place
buildingBrickRed.Parent = workspace
buildingBrickRed.Anchored = true
buildingBrickRed.BrickColor = BrickColor.new("Really red") -- makes the brick red
buildingBrickRed.Size = Vector3.new(size,size,size ) -- sets the size of the block
buildingBrickRed.CFrame = CFrame.new(Vector3.new(tempX * size,tempY * size , tempZ * size)) -- sets the position of the block to be where the mouse is 

end

hammer.Activated:Connect(placeBlock) --connects to the function when the player activates the tool

Any feedback / tutorial link is appreciated!

Note that I have browsed the forum quite a bit and didn’t find a good straight-forward tutorial on how to build a placement system so sorry if the code is a bit messy!

7 Likes

Hi alexstar493303!

I believe what you are trying to achieve is known as Grid Placement System.
I have actually created a place regarding this particular topic, so here is the place file:
GPS.rbxl (19.1 KB)
You can closely look through the scripts, the Explorer hierarchy, and more. This can give you an idea of how you need to write the code to position the blocks correctly.

Hope that helps!

14 Likes

will defenetly be checking this out, thanks!

1 Like

Look into game.Workspace:FindPartOnRay(…); according to the API reference, it returns the part hit, the point of intersection, and THE SURFACE NORMAL WHERE THE RAY HIT. Using the surface normal, you can change your code a bit from
local tempX = math.floor((position.X / size )+0.5)
local tempY = math.floor((position.Y / size)+0.5)
local tempZ = math.floor((position.Z / size) +0.5)
to
local tempX = math.floor((position.X / size )+normal.X/2)
local tempY = math.floor((position.Y / size)+normal.Y/2)
local tempZ = math.floor((position.Z / size) +normal.Z/2)
where normal represents the surface normal returned by GetPartOnRay (the normal vector is, well, normalized, so normal.X/Y/Z would never exceed the range [-1,1]).
Hope this helps! :slight_smile:

5 Likes