function PlacementController:GetMousePoint(ignoreList)
if mouse.Target ~= nil then
local unitRay = camera:ScreenPointToRay(mouse.x, mouse.y)
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = ignoreList
local ray = workspace:Raycast(unitRay.Origin, unitRay.Direction * range, raycastParams)
if ray then
return ray.Position, ray.Instance, ray.Normal
end
end
end
function Snap(position)
PosX = math.floor(position.X / Grid + 0.5) * Grid -- Snaps
PosY = position.Y -- Change this to your Y
PosZ = math.floor(position.Z / Grid + 0.5) * Grid
end
function PlacementController:Start()
local ignoreList = {char, Sign}
RunService.RenderStepped:Connect(function()
local position, target, normal = self:GetMousePoint(ignoreList)
if target == game.Workspace.Part then
Snap(position)
Sign:SetPrimaryPartCFrame(Sign.PrimaryPart.CFrame:Lerp(CFrame.new(PosX,PosY, PosZ) * CFrame.new(0, 2, 0), 0.5))
end
end)
Use align position and create boxs which only it can collide with. Since you seem to be on a 2d grid you can use a aabb system to glitch it back in bounds
You have to keep it placementPart.size.X/2 away from either side. You should pretend that the baseplate is its size - placementPart.Size and then go from there. If you need it to handle rotated objects its a bit more tricky and you would need to essentially determine the smallest axis aligned box that would fit the whole thing for it first then do the same thing with that box.
get the size of the placement pad
get the size of the part
pretend the placement pad size is placementPad.Size - part.Size
check that the mouse point is withing the bounds of the placement parts pretendSize
Note that this would only work on a rectangular baseplate. Any other baseplate shapes would need a different method or an adjustment to this one.
That is essentially it I think, it just does not factor in the size of the piece that is being placed. It will clamp it, but it will allow the middle of the piece to go all the way to the bounds letting the edges go past. To fix that you have to pretend that the base.Size = base.Size - placementPart.Size. Then divide that by 2
They simply forgot to close the last parenthesis. This is a small modification to their code that fixes the out of bounds error you would still get by factoring in the size of the part you are placing in the variable
Here is a simplified version of the code, tell me if it throws another error. One thing to note is that I’m assuming the Sign.PrimaryPart.Size covers the entirety of the sign, otherwise this won’t work.
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local camera = workspace.CurrentCamera
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Folder = ReplicatedStorage.GameClient
local Models = Folder.Models
local char = player.Character or player.CharacterAdded:Wait()
local Sign = Models.Sign:Clone()
local Grid = 0.5
local PosX
local PosY
local PosZ
local Part = game.Workspace.Part
Sign.Parent = game.Workspace
-- Customize:
local range = 250 -- Mouse object move range
function PlacementController:GetMousePoint(ignoreList)
if mouse.Target ~= nil then
local unitRay = camera:ScreenPointToRay(mouse.x, mouse.y)
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = ignoreList
local ray = workspace:Raycast(unitRay.Origin, unitRay.Direction * range, raycastParams)
if ray then
return ray.Position, ray.Instance, ray.Normal
end
end
end
local base = Part
function Snap(position)
local fakeSize = (base.Size - Sign.PrimaryPart.Size)/2
PosX = base.Position.X + math.clamp(Sign.PrimaryPart.Position.X, -fakeSize.X, fakeSize.X)
PosZ = base.Position.Z + math.clamp(Sign.PrimaryPart.Position.Z, -fakeSize.Z, fakeSize.Z)
PosY = position.Y -- Change this to your Y
end
function PlacementController:Start()
local ignoreList = {char, Sign}
RunService.RenderStepped:Connect(function()
local position, target, normal = self:GetMousePoint(ignoreList)
if target == game.Workspace.Part then
Snap(position)
if PosX >= -99.5 then
Sign:SetPrimaryPartCFrame(Sign.PrimaryPart.CFrame:Lerp(CFrame.new(PosX,PosY, PosZ) * CFrame.new(0, 2, 0), 0.5))
end
end
end)
end