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) :
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
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