Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How can I improve my block placement system?

Before commenting "This isn't a request site" please read the entire post.

I made a block placement system but when I place block, unless it is being placed on the ground or on top of another block, 1 to 2 studs get pushed inside the side of the part you are placing on.

What happens: https://ibb.co/MgHvkGh

What supposed to happen: https://ibb.co/xsM9ym5

(Not a ip logger)

Here is my code for the hover placing:

script.Parent.Equipped:Connect(function() -- Activate when tool eqquiped
	if mouse ~= nil then -- Check if mouse exists
		eqquiped = true
		local clone = game.ReplicatedStorage.Dirt:Clone() -- Creates clone
		clone.Name = "placing"
		mouse.TargetFilter = clone -- Mouse not effected by clone
		for i,v in pairs(clone:GetChildren()) do -- Set all parts to transparency 0.5
			if v.Name ~= "hit" then
				v.Transparency = 0.5
			end
		end
		clone.Parent = workspace -- Move the part
		mouse.Move:Connect(function()
			if eqquiped then
				if clone then
					clone:SetPrimaryPartCFrame(CFrame.new(snap(mouse.Hit.p,3))) -- Set the part position	
				end
			end	
		end)
	end
end)

Code for actual placing:

script.Parent.Activated:Connect(function()
	local clone = game.ReplicatedStorage.Dirt:Clone() -- Creates clone
	clone.Parent = workspace -- Move the part
	clone:SetPrimaryPartCFrame(CFrame.new(snap(mouse.Hit.p,3))) -- Set the part position
	
end)

snap() is a function that takes in a vector3 and a float, it returns a vector3 snapped to a grid:

function snap(pos,grid)
	return Vector3.new(
		math.floor((pos.X / grid) * grid + 0.5),
		math.floor((pos.Y / grid) * grid + 2),
		math.floor((pos.Z / grid) * grid + 0.5)
	)
end

My idea is that the block ejects out of the part you are hovering over, but still keep the grid system.

1 answer

✓ Accepted answer

the snap function is written incorrectly

when you do (pos.axis/grid) * grid, it just gives you the original position of that axis, meaning that your block positions are rounded to the nearest integer

you have to multiply after flooring the number:

function snap(pos, grid, normal)
	normal = normal or Vector3.new() -- if the normal isn't present, default to not using one at all
	normal *= grid/2 -- make it so the length of the normal is half the size of the grid
    return Vector3.new(
        math.floor((pos.X + normal.X) / grid + 0.5) * grid,
        math.floor((pos.Y + normal.Y) / grid + 0.5) * grid,
        math.floor((pos.Z + normal.Z) / grid + 0.5) * grid
    )
end

for the block to not intersect with the surface it's on, you have to add the normal of the surface the mouse is hovering over, which just means its direction

you can't get the surface normal just using the mouse object, but it's not too hard to do it manually using raycasting

mouse.Move:Connect(function()
	local params = RaycastParams.new()
	params.FilterDescendantsInstances = {clone, game.Players.LocalPlayer.Character}
	params.IgnoreWater = true
	params.FilterType = Enum.RaycastFilterType.Blacklist
	local result = workspace:Raycast(mouse.UnitRay.Origin, mouse.UnitRay.Direction * 200, params)
	if result and clone then
		clone:SetPrimaryPartCFrame(CFrame.new(snap(result.Position, 3, result.Normal)))
	end
end

also, you should consider disconnecting the mouse.Move connection later, since if you don't disconnect connections when you're done with them it can cause memory leaks

21 comments

0

It dosnt work. It ejects the block out of the side but it is a bit off the ground

0

i updated the answer to ((((hopefully)))) work now

0

in the snap function what would normal be? when i call the function?

0

you don't have to include it if you're just trying to snap a normal position to the grid, but when you use it for block placement, it's the normal of the surface the player is hovering over

0

i included some code that does it for you

0

the snap function need to be in a cframe, so it looks like this : CFrame.new(snap(arg,arg2,arg3)

0

oops you're right, my bad

0

this is almost working but the block is being placed on the side of the block that is being placed (the transparent one)

0

try adding the transparent clone to the filter list when you actually place the block

0

where is the filter?

0

wait dont tell me i need to figure this out on my own

0

the filter is the line that sets params.FilterDescendantsInstances

0

the filter is the line that sets params.FilterDescendantsInstances

0

the clone is already in the blacklist

0

no, i mean the transparent clone, the clone variable when you place the block is different than the transparent clone variable

0

you need to create a transparentClone variable at the top of the script and set the transparent clone to that

0

what would i set t he transparent clone value to be?

0

you don't need to set it to anything until the player equips the tool

0

oh im dumb i need to set this in the placing part of the script! my bad

0

thanks you you are the first person to actually attempt to anwser my question!'

0

np

This discussion is preserved as it was. New answers, comments, and votes are closed.