Hello! I am trying to make a placement system with a grid and it kind of works but I have encountered a problem.
I can place blocks wherever I want on the ground but whenever I try to place a block on a side of another block, it is only possible to do this on a certain side. For example, I can only place blocks on the right and bottom side but not on the left and top side if I try to do so the block will be placed inside the other block. Has anyone ever had this problem as well and knows how to fix this?
This is my code:
local LocalPlayer = game.Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()
local function round(n)
return math.floor(n + 0.5)
end
Mouse.Button1Down:Connect(function ()
local xRound = round(Mouse.Hit.X)
local yRound = round(Mouse.Hit.Y)
local zRound = round(Mouse.Hit.Z)
local Block = game.ReplicatedStorage.Blocks.Block:Clone()
Block.Position = Vector3.new(xRound, yRound, zRound)
Block.Parent = workspace
end)
Hi! I’ve made gif about my problem and as you can see I can only place blocks on certain sides of the other block. (I know it’s a fast gif but it wouldn’t allow me to make longer ones, sorry)
I would opt for using a modulus based grid system rather than rounding
More reliable
local gridOrigin = Vector3.new() --any point on the grid, used as starting point
local gridSize = 1 --size of grid
function toGrid(pos)
local npos = pos-gridOrigin
return Vector3.new(pos.X-npos.X%gridSize,pos.Y-npos.Y%gridSize,pos.Z-npos.Z%gridSize)+Vector3.new(gridSize/2,gridSize/2,gridSize/2)
end
Hi! So I have tried both your solutions and they didn’t really work the way I expected them to work, but I have solved the problem. Here is my code for anyone wondering:
local player = game.Players.LocalPlayer
local Ignore_Blocks = game.Workspace:WaitForChild("Ignore_Blocks")
local mouse = player:GetMouse()
mouse.TargetFilter = Ignore_Blocks
local target = nil
local pos = nil
local norm = nil
local MAX_PLACEMENT_DISTANCE = 2000
function doFakeMouseStuff()
local ignoreList = {Ignore_Blocks, player.Character}
local mouseRay = mouse.UnitRay
local newRay = Ray.new(mouseRay.Origin, mouseRay.Direction.unit * MAX_PLACEMENT_DISTANCE)
target, pos, norm = workspace:FindPartOnRayWithIgnoreList(newRay, ignoreList)
end
game:GetService("RunService").RenderStepped:connect(function()
doFakeMouseStuff()
end)
function round(vec, block)
local posx = math.floor(vec.X / block.PrimaryPart.Size.X + 0.5) * block.PrimaryPart.Size.X
local posy = math.floor(vec.Y / block.PrimaryPart.Size.Y + 0.5) * block.PrimaryPart.Size.Y
local posz = math.floor(vec.Z / block.PrimaryPart.Size.Z + 0.5) * block.PrimaryPart.Size.Z
return Vector3.new(posx, posy, posz)
end
local item = workspace:WaitForChild('GhostBlock')
item.Parent = Ignore_Blocks
mouse.Move:connect(function()
if item and pos and norm then
doFakeMouseStuff()
local endPos = round(pos + (norm * (item.PrimaryPart.Size*.5)), item)
item:SetPrimaryPartCFrame(CFrame.new(endPos))
end
end)
mouse.Button1Down:connect(function()
local part = item:Clone()
part:SetPrimaryPartCFrame(CFrame.new(item.PrimaryPart.Position))
part.Name = 'block'
part.Parent = workspace
local set = part.PrimaryPart
set.Color = Color3.new(163, 162, 165)
set.Transparency = 0
set.CanCollide = true
end)