Block-placing system (similar to Minecraft) behaves weirdly when trying to place blocks

This is my localscript, which is only client-sided at the moment for testing.

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

local posX
local posY
local posZ 
local gridSize = 4
local Part = workspace.MovePart
local point

local function Snap()
	point = mouse.Target
	mouse.TargetFilter = Part
    posX = math.floor(mouse.Hit.X / gridSize + 0.5) * gridSize 
	posY = math.floor(mouse.Hit.Y / gridSize + 0.5) * gridSize + 2
	posZ = math.floor(mouse.Hit.Z / gridSize + 0.5) * gridSize
	Part.Position = Vector3.new(posX, posY, posZ)
end

local function Place()
	print("I work...")
	local newPart =  Part:Clone()
	newPart.Name = "Test"
	newPart.Parent = workspace
end


mouse.Move:Connect(Snap)
mouse.Button1Down:Connect(Place)

Here’s a video demonstrating the issue, the block will go inside of other blocks instead of going on the side of the wall.


(don’t mind the video quality, you can see the block preview doesn’t work correctly while going on certain sides, and the block will be placed within the other block.)

Try doing (gridsize + 0.5) lmk if that worked

Where? I already have it in the position variables

Like right here, add some brackets

before and after gridSize + 0.5

It actually created more of an issue, seems like whenever you face the direction I was building on it’s offset by a couple studs
I was building on the wrong block… it still has the same issue as before after using the right wall

It looks like it’s being rounded to the closest positive direction maybe since you’re already flooring it you could take off the 0.5?

That ended up “flipping” the sides it worked on, as if before it worked on side A and B (just as an example) and now it only works on side C and D.

I used to have this issue too, but I found a way to get around it. In your case, I would probably do the same as I did. I used the Unit of the mouse’s target’s position subtracted by the mouse’s hit position and multiplied it by -gridsize. So, I believe something like this will work:

local function Snap()
	point = mouse.Target
	mouse.TargetFilter = Part
	posX = math.floor(mouse.Hit.X / gridSize + 0.5) * gridSize
	posY = math.floor(mouse.Hit.Y / gridSize + 0.5) * gridSize + 2
	posZ = math.floor(mouse.Hit.Z / gridSize + 0.5) * gridSize

	if point then
		posX = posX + (point.Position - mouse.Hit.p).Unit * -gridSize
		posX = math.floor(posX)

		posZ = posZ + (point.Position - mouse.Hit.p).Unit * -gridSize
		posZ = math.floor(posZ)
	end

	Part.Position = Vector3.new(posX, posY, posZ)
end

now, I’m not exactly sure how to incorporate it into yours as you have a completely different style than I do, but this should work. If not, I’ll send you the part of my script I did it in and try to work a way around the differences.

posX = posX + (point.Position - mouse.Hit.p).Unit * -gridSize

This line gives Players.Abnumality.PlayerScripts.LocalScript:18: attempt to perform arithmetic (add) on number and Vector3 this error.

oh, sorry. Here:

local function Snap()
	point = mouse.Target
	mouse.TargetFilter = Part
	posX = math.floor(mouse.Hit.X / gridSize + 0.5) * gridSize
	posY = math.floor(mouse.Hit.Y / gridSize + 0.5) * gridSize + 2
	posZ = math.floor(mouse.Hit.Z / gridSize + 0.5) * gridSize

	if point then
		posX = posX + (point.Position - mouse.Hit.p).Unit.X * -gridSize
		posX = math.floor(posX)

		posZ = posZ + (point.Position - mouse.Hit.p).Unit.Z * -gridSize
		posZ = math.floor(posZ)
	end

	Part.Position = Vector3.new(posX, posY, posZ)
end

robloxapp-20220601-1939389.wmv (1.9 MB)
That ended up causing this to happen, apologies for wmv format…

Actually, now that I realize it myself, I did it the completely wrong way. I should’ve used the part’s position and not the original posX and posZ. Here:

local function Snap()
	point = mouse.Target
	mouse.TargetFilter = Part
	posX = math.floor(mouse.Hit.X / gridSize + 0.5) * gridSize
	posY = math.floor(mouse.Hit.Y / gridSize + 0.5) * gridSize + 2
	posZ = math.floor(mouse.Hit.Z / gridSize + 0.5) * gridSize

	if point then
		local neededpos = point.Position + (point.Position - mouse.Hit.p).Unit * -gridSize
		posX = neededpos.X
		posZ = neededpos.Z
		posY = neededpos.Y
	end

	Part.Position = Vector3.new(posX, posY, posZ)
end

Since you’re doing a 4x4 grid and each block is 4x4 it would explain why it’s snapping to the positive or negative direction when adding or subtracting 0.5 you need some way detecting blocks being collided or checking the surroundings of the block

Yeah, I should probably switch to some kind of different building system for this, it’s probably going to cause too much trouble later on

1 Like

May I suggest getting the normals unit of your mouse hit then times it with every 0.5 so it either goes in the negative or positive direction

1 Like