Problem with putting the selection box at the correct position

local snappedPos
local oldSnappedPos

local canplace = false


function GetClosestMultiple(x)
	return x // 4 * 4
end

local castParams = RaycastParams.new()
castParams:AddToFilter(script.Parent)


script.MoveToPart.CFrame = workspace:WaitForChild("Default").CFrame
script.MoveToPart.SelectionBox.Transparency = 1

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

game:GetService("RunService").RenderStepped:Connect(function()
	local mouselocation = game:GetService("UserInputService"):GetMouseLocation()
	local unitray = workspace.CurrentCamera:ViewportPointToRay(mouselocation.X, mouselocation.Y)
	local pos = workspace:Raycast(unitray.Origin, unitray.Direction * 1000, castParams)
	
	if pos == nil then
		return
	end

	local x = pos.Position.X
	local y = pos.Position.Y
	local z = pos.Position.Z

	local newX = GetClosestMultiple(x)
	local newY = GetClosestMultiple(y)
	local newZ = GetClosestMultiple(z)

	local PlacePos = Vector3.new(newX, newY, newZ)
	--print("New block position: "..newX..", "..newY..", "..newZ)

	local existingPart = game.Workspace.ClientStorage:FindFirstChild("MoveToPart")
	if existingPart then
		existingPart:Destroy()
	end

	local mtp = script.MoveToPart:Clone()


	local normalcf = CFrame.lookAlong(pos.Position, pos.Normal)
	local relsnap = normalcf:PointToObjectSpace(PlacePos)
	local xVector = normalcf:VectorToWorldSpace(Vector3.xAxis * -math.sign(relsnap.X))
	local yVector = normalcf:VectorToWorldSpace(Vector3.yAxis * -math.sign(relsnap.Y)) 

	local cf = CFrame.fromMatrix(PlacePos, xVector, yVector, pos.Normal)
	mtp.SelectionBox.Transparency = 0
	
	local offset = pos.Normal * (mtp.Size / 2)

	if pos.Instance:FindFirstChild("Owner") then
		mtp.Position = pos.Instance.Position
	else
		mtp.Position = PlacePos - offset
	end

	local olParams = OverlapParams.new()
	
	for i, v in ipairs(workspace:GetChildren()) do
		for i, p in ipairs(game.Players:GetChildren()) do
			if v ~= p.Character then
				olParams:AddToFilter(v)
			end
		end
	end

	
	local touching = workspace:GetPartsInPart(mtp, olParams)
	
	if #touching == 0 then
		canplace = true
		snappedPos = cf:PointToWorldSpace(mtp.Size / 2)
	else
		canplace = false
		mtp.SelectionBox.Color3 = Color3.new(1,0,0)
	end
	mtp.Parent = game.Workspace.ClientStorage
end)


mouse.Button2Down:Connect(function()
	if canplace then
		game.ReplicatedStorage.Events.PlaceBlock:FireServer(snappedPos)
	end
end)

As seen in the image, the block is placed correctly but the white outline is not. Anyone know a fix?

The white outline calculation part:

	local offset = pos.Normal * (mtp.Size / 2)

	if pos.Instance:FindFirstChild("Owner") then
		mtp.Position = pos.Instance.Position
	else
		mtp.Position = PlacePos - offset
	end
1 Like

bumping this because i havent gotten an answer for 5 hours

bumping AGAIN since nobody has responded for half a day

Why PlacePos - offset tho?
Offest supposed to be added to current position

The most part of the code logic is wrong.
You are supposed to snap the position after all calculations, not to mix the snapped position and offest
The code is also complicate for no reason, lol

function handler:PlacingTool(tool :Tool)
	
	local block = script.Outline:Clone()
	local endPos = Vector3.new()
	
	tool.Activated:Connect(function()
		--print("click")

		self:Place(tool.Name, endPos)
	end)

	tool.Equipped:Connect(function()
		--print("equipped")
		block.Parent = workspace.Temp
		rs:BindToRenderStep("BlockPreview", Enum.RenderPriority.Input.Value + 1, function(deltaTime)
			local ray = handler:MouseToWorld()
			
			if ray and ray.Position then
				endPos = snapUtils(ray.Position + ray.Normal, 3)
				if (endPos - plr.Character:GetPivot().Position).Magnitude > 25 then
					endPos = handler:BridgeRay()
				end
				block.Position = endPos
			else
				endPos = handler:BridgeRay()
				block.Position = endPos
			end
		end)
	end)

	tool.Unequipped:Connect(function()
		--print("unequipped")
		rs:UnbindFromRenderStep("BlockPreview")
		block.Parent = nil
	end)
	
	tool.Destroying:Connect(function()
		--print("TOOL IS DESTROYING!!!!")

		rs:UnbindFromRenderStep("BlockPreview")
		block:Destroy()
	end)
end

This is how i do my placing stuff

EDIT:
The snapUtil function

local function round(n, gridSize)
	local absN = math.abs(n)
	local remainder = absN%gridSize
	if remainder < gridSize*.5 then
		return math.sign(n)*(absN-remainder)
	else return math.sign(n)*(absN-remainder+gridSize)
	end
end

return function(pos, grid)
	return Vector3.new(
		round(pos.X, grid),
		round(pos.Y, grid),
		round(pos.Z, grid)
	)
end
2 Likes

oh thanks, didnt see this until now!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.