How do you make a building feature?

So read the title:

  1. I want to make a building feature like the games such as minecraft, islands and bedwars have. Keep it simple and clear!

  2. Here is what I’m talking about:
    Building My New Island in Roblox Islands (Part 1 of 3) - YouTube

There are blocks in your inventory to build.

  1. I have tried looking at youtube videos but I did not find the one I want.

I really appreciate it when I know how to make this for a game I’m working on!
Thanks.

1 Like

If you can make sort of like a grid system. I would make it locked to 3,3,3 grid size and whenever you place a block, get the block normal (via a camera raycast) and multiply it by 3. If your block isn’t a full block what I did was create a ghost block, put it at the block’s CFrame, then cast again and get the normal based on that ghost block.

I am a beginner scripter so I don’t understand what you’re saying… Can you explain it in an easier way?

You Answer Is Mouse.hit.p

Do This:

game.Player.LocalPlayer:GetMouse().Button1Down:Connect(function() -- Button1Down = Left Mouse Button
local Position = game.Player.LocalPlayer:GetMouse().Hit.p
-- make part bla bla bla
end)

What do you mean by ‘make part bla bla’?

the process of making a part :confused:

2 Likes

It means inserting a new part by Instance.new() or cloning a part

It has very tutorials on yt, showing make like minecraft system.

search placement system

I get it. You’re trying to make a building system, something like Piggy: Build mode?

1 Like

@Qinrir and @AridFights1 Now I understand! But how do you make like an inventory with different blocks, and you can select it and place?

i Did Made A Minecraft Like game but Never was Able To Make Inventory

1 Like

There are multiple ways of making a grid placement system.
Here are some:

  1. Where do I start with a grid placement system?
  2. https://scriptinghelpers.org/questions/45569/a-basic-walkthrough-of-a-grid-placement-system
  3. How to Make A Placement System in Roblox Studio - YouTube [It’s a good tutorial]
1 Like

also not to mention if you do grid placement sometime it break meaning when you click in the negative axis the code dosent work as intended to it places the part in another part the way around this is lengthy

2 Likes

Here’s one of my posts I made earlier, a few months ago. (Still couldn’t solve it)

yes i know also @OhLordiez ill be back after making the code ok

2 Likes

Try this video.

just a bit of info, you can lock it to a grid by doing

 vector3.new(math.ceil(position.x/3), math.ceil(position.y/3), math.ceil(position.z/3))*3

to get the block normal via a camera raycast you can use this function
(mouse.hit.position is good and all but this gives a concrete ignore list)

local UIS = game:GetService("UserInputService")
function RaycastToScreenPos(screenpos, ignorelist, ignoretype)
	local camray = workspace.CurrentCamera:ScreenPointToRay(screenpos.x, screenpos.y)
	local CastInfo = RaycastParams.new()
	CastInfo.FilterType = ignoretype or Enum.RaycastFilterType.Blacklist
	--blacklist ignores all in your ignore list, whitelist only goes for the ones in the list
	CastInfo.FilterDescendantsInstances = ignorelist or {}
	local NewRayResult = workspace:Raycast(camray.Position, camray.Direction * 100000, CastInfo)
	--long ray
	return NewRayResult
end

local result = RaycastToScreenPos(UIS:GetMouseLocation(), {--[[stuff to ignore goes in here]] }, Enum.RaycastFilterType.Blacklist)

result.Normal = direction of the face you hit (normal)
result.Instance  = the part you hit
result.Position = the position of your hit
result.Material = the material of what you hit

putting this all together you can make a placement system with this function in a serverscript

local TemplateContainer = folder where you keep your block templates
local BlocksFolder = folder where blocks are put in Workspace
local PlaceBlockRemote = place block remote

function PlaceBlock(plr, templatename, Normal, Position, hitinst) 
	local Block = TemplateContainer:FindFirstChild(templatename):Clone()
	Block.Position = hitinst.Position+Normal.Unit*3
	Block.Parent = BlocksFolder
end

PlaceBlockRemote.OnServerEvent:Connect(function(plr, templatename, Normal, Pos, Hitinst)
	--put your checks here
	PlaceBlock(plr, templatename, Normal, Pos, Hitinst)
end)

above is easily hackable by firing a remote, add some server checks (ie if player is in range, if player has enough blocks in slot, etc)

and you need the placement system for client

local UIS = game:GetService("UserInputService")
local PlacementRemote = remote for placement

function RaycastToScreenPos(screenpos, ignorelist, ignoretype)
	local camray = workspace.CurrentCamera:ScreenPointToRay(screenpos.x, screenpos.y)
	local CastInfo = RaycastParams.new()
	CastInfo.FilterType = ignoretype or Enum.RaycastFilterType.Blacklist
	--blacklist ignores all in your ignore list, whitelist only goes for the ones in the list
	CastInfo.FilterDescendantsInstances = ignorelist or {}
	local NewRayResult = workspace:Raycast(camray.Position, camray.Direction * 100000, CastInfo)
	--long ray
	return NewRayResult
end

function PlaceBlock()
	local result = RaycastToScreenPos(UIS:GetMouseLocation(), {--[[stuff to ignore goes in here]] }, Enum.RaycastFilterType.Blacklist)
	--im not going to add ghost blocks because i have worked on this for a bit longer than i would have liked to
	PlacementRemote:FireServer("TemplateName(set this to template name)", result.Normal, result.Position, result.Instance)
end
--bind above to mouse button click or smth

this is just concept code and im not 100% sure it will work. hopefully it will tho

1 Like

aaaaaaaaaaaaaaaaaaaaaaand Done! @OhLordiez
Done This Works Just As Old Minecraft

local Mouse = game.Players.LocalPlayer:GetMouse()
local function RoundDown(X)
	return Vector3.new(math.floor(X.X),math.floor(X.Y),math.floor(X.Z))
end
Mouse.Button1Down:Connect(function()
	local snap = 3 -- Grid
	local Surface = Mouse.TargetSurface
	local Pos = Mouse.Hit.p
	
	if Surface == Enum.NormalId.Top then
		Pos = Pos + Vector3.new(0, snap, 0)

	elseif Surface == Enum.NormalId.Bottom then
		Pos  = Pos - Vector3.new(0, snap, 0)

	elseif Surface == Enum.NormalId.Left then
		Pos  = Pos - Vector3.new(snap, 0, 0)

	elseif Surface == Enum.NormalId.Right then
		Pos = Pos + Vector3.new(snap, 0, 0)

	elseif Surface == Enum.NormalId.Front then
		Pos = Pos - Vector3.new(0, 0, snap)

	elseif Surface == Enum.NormalId.Back then
		Pos = Pos + Vector3.new(0, 0, snap)
	end
	Pos = RoundDown(Pos)
	local Part =Instance.new("Part",game.Workspace)
	Part.Anchored = true
	Part.Size = Vector3.new(3,3,3)
	Part.Position = Pos
end)

Also I Didnt Made It For Server Meaning Only You Can See Blocks For Server Sided I Leave It Upon You As Its Not That Hard

1 Like

Sorry to say but it only works on one axis

You can make an event, so that when you click then you can fire a remote event.