Placement system only working on one side of a part

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)

Thanks in advance!

2 Likes

you could just use

local LocalPlayer = game.Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()

Mouse.Button1Down:Connect(function ()

local xRound = math.round(Mouse.Hit.p.X)
local yRound = math.round(Mouse.Hit.p.Y)
local zRound = math.round(Mouse.Hit.p.Z)


    local Block = game.ReplicatedStorage.Blocks.Block:Clone()
    Block.Position = Vector3.new(xRound, yRound, zRound)
    Block.Parent = workspace
end)

and idk wheres the script that shows the position scan?

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)

https://i.gyazo.com/6982c01cb30322c5b4685ccf9ba632e9.gif

And what do you mean with ‘script that shows the position scan’?

hmm, I mean all ur parts seem like 1x1x1 so basically you could just do

    local Block = Instance.new("Part")
Block.Size = Vector3.new(1,1,1)  Block.Anchored = true Block.Position =  Vector3.new(xRound, yRound, zRound) Block.Parent = workspace

Since I think the part isn’t fully 1x1x1 square.

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)
2 Likes

What’s the change here?
I’m also having the same issue but want to implement the fix to my own code, can someone help? thanks