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