Coding a grid-based object placement system & having trouble getting objects to place on a part.
Issue: Object ends up partially or completely inside the part instead of on the part’s surface.
Can’t seem to find a solution anywhere.
Code below. Looking for any suggestions or fix.
Thank you.
local players = game:GetService("Players")
local runService = game:GetService("RunService")
local object = game:GetService("ReplicatedStorage").Items["Plank Tile"]:Clone() -- "Plank Tile" is a 3x3x1 part
object.Parent = game:GetService("Workspace").ItemHolder
local primary = object.PrimaryPart
local player = players.LocalPlayer
local mouse = player:GetMouse()
mouse.TargetFilter = object
-- Offsets equal to half of object's size
local offsetX = primary.Size.X*0.5
local offsetY = primary.Size.Y*0.5
local offsetZ = primary.Size.Z*0.5
-- Function that rounds the object's position to the nearest stud
local function snap(pos)
local newX = math.round(pos.X)
local newY = math.round(pos.Y)
local newZ = math.round(pos.Z + 0.5) - 0.5
return CFrame.new(newX,newY,newZ)
end
-- Function that handles where the object will be placed
function placement()
local posX = mouse.Hit.X
local posY = mouse.Hit.Y
local posZ = mouse.Hit.Z
local pos = CFrame.new(posX, posY, posZ)
local snappedPos = snap(pos)
local surface = mouse.TargetSurface
-- Pivots object to the desired position and applies offset depending on the face of the target part
if surface.Name == "Top" then
local finalCFrame = object:PivotTo(CFrame.new(snappedPos.X, snappedPos.Y + offsetY, snappedPos.Z))
elseif surface.Name == "Bottom" then
local finalCFrame = object:PivotTo(CFrame.new(snappedPos.X, snappedPos.Y - offsetY, snappedPos.Z))
elseif surface.Name == "Left" then
local finalCFrame = object:PivotTo(CFrame.new(snappedPos.X - offsetX, snappedPos.Y, snappedPos.Z))
elseif surface.Name == "Right" then
local finalCFrame = object:PivotTo(CFrame.new(snappedPos.X + offsetX, snappedPos.Y, snappedPos.Z))
elseif surface.Name == "Front" then
local finalCFrame = object:PivotTo(CFrame.new(snappedPos.X, snappedPos.Y, snappedPos.Z - offsetZ))
elseif surface.Name == "Back" then
local finalCFrame = object:PivotTo(CFrame.new(snappedPos.X, snappedPos.Y, snappedPos.Z + offsetZ))
end
end
runService:BindToRenderStep("PlacementLoop", 1, placement)