Help with building system

I’m trying to make a building system similar to Bedwars’ one. The thing is, I don’t know how to make it that when you hover over the void the block would be placed right at the edge
(example video since im bad at explaining things) :

How would I go about doing this?

Thanks,
RGF

Use Mouse.TargetFilter to make a preview block. Set the preview block(s) transparency and collision to false. Use selection boxes.

I already have, I’m just trying to learn how to have it that when your mouse is hovering over the void it behaves like it did in the video

1 Like

So I just hopped into a bedwars game and I noticed something, you can only place void blocks at the current y level that you are at, it also has a max distance of 3 blocks i think, so with this into account all you have to do is simply:

local valid_blocks = {}
for _, v in pairs(Folder With All Blocks On It) do
 if --[[ do a check where if the blocks are at the players y level,
 and if player is within the distance of the block]] then
 table.insert(valid_blocks, v)
  
end
end

local all_distances = {}
for _, v in pairs(valid_blocks) do
 local mousehit = mouse.Hit.Position
 local distance = (mousehit - v.Position).Magnitude
 table.insert(all_distances, distance)
end

-- Sort Them and find the closest one then position how you want to

Doesn’t work. Tried multiple methods

How about this? I’m too lazy to make it actually set the position after but you can get the idea. if you place a couple premade blocks down you can see this work.

THIS IS VERY JANKY!!! MEANT FOR DEMONSTATION

Requirments:

  • A 4x4 anchored part transparency set to 1 in Replicated Storage
  • Remote Function Called ‘PlaceBlockFunction’ in Replicated Storage
    -The Following Local Script
repeat wait() until game.Players.LocalPlayer.Character
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()

local rs = game:GetService('ReplicatedStorage')
local uis = game:GetService("UserInputService")
local runs = game:GetService('RunService')

local block = rs:WaitForChild('Block'):Clone()
local pbfunc = rs:WaitForChild('PlaceBlockFunction')
block.Parent = workspace
block.CanCollide = false
mouse.TargetFilter = block

local selectbox = Instance.new('SelectionBox', player.PlayerGui)
selectbox.Adornee = block

local function customround(number, roundto) return math.round(number / roundto) * roundto end

runs.RenderStepped:Connect(function()
	local pos = mouse.Hit.Position
	local lock = 4
	
	if mouse.Target then
		block.Position = Vector3.new(customround(pos.X, lock), customround(pos.Y, lock), customround(pos.Z, lock))
	else -- Void Stuff Here Below is what I was talking about and it works
		local closest
		local vector = pos - workspace.CurrentCamera.CFrame.Position
		local direction = vector.Unit
		local distance = vector.Magnitude
		if distance > 20 then distance = 20 end
		local final = workspace.CurrentCamera.CFrame.Position + direction * distance
		block.Position = final

		for _, v in pairs(workspace.PlacedBlocks:GetChildren()) do
			
			if closest == nil then
				closest = v
			else
				if (final - v.Position).Magnitude < (final - closest.Position).Magnitude then
					closest = v
				end
			end
		end
		block.Position = closest.Position
	end
	
end)

mouse.Button1Down:Connect(function()
	local clonedBlock = pbfunc:InvokeServer(block.CFrame)
end)
  • The Following Script
local rs = game:GetService('ReplicatedStorage')

local block = rs:WaitForChild('Block')
local pbfunc = rs:WaitForChild('PlaceBlockFunction')

local function createWall(player, cf)
  local new = block:Clone()
  new.Transparency = 0
  new.Parent = workspace.PlacedBlocks
  new.CFrame = cf
  return new
end

pbfunc.OnServerInvoke = createWall

Hope This Helps!