How to make grid placement relative to part position?

Hi, i’m having problems with making this relative to part in workspace, script:

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

local grid = 4

local function OnRound(n:number,m:number)
	local x = n + (m/2)
	
	return x-(x%m)
end


mouse.TargetFilter = workspace.Block

mouse.Move:Connect(function()
	
	


	
end)
mouse.Button1Down:Connect(function()
	local clone = workspace.Block:Clone()
	clone.Name = "Placed"
	clone.Parent = workspace
	clone.CanCollide = true
	
	
end)

this is local sript that imitates grid placing system, but it’s only world space, anyone know how to snap it to other parts in workspace?

Convert the “un-snapped” position to the part’s object space, snap it in that space, then convert back to world space.

Generated by ChatGPT:

To make the grid placement relative to another part in the workspace, you can use the mouse.Target property to get the part that the mouse is hovering over, and then position the new part relative to that part’s position.

Here’s an updated script that should work:

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

local grid = 4

local function OnRound(n, m)
	local x = n + (m / 2)
	return x - (x % m)
end

mouse.TargetFilter = workspace.Block

mouse.Move:Connect(function()
	-- Calculate the snapped position based on the grid size
	local hit = mouse.Target
	if hit then
		local snappedPos = Vector3.new(
			OnRound(hit.Position.X, grid),
			OnRound(hit.Position.Y, grid),
			OnRound(hit.Position.Z, grid)
		)
		-- Position the clone relative to the hit part
		clone.Position = snappedPos + Vector3.new(grid / 2, grid / 2, grid / 2)
	end
end)

mouse.Button1Down:Connect(function()
	local hit = mouse.Target
	if hit then
		local clone = workspace.Block:Clone()
		clone.Name = "Placed"
		clone.Parent = workspace
		clone.CanCollide = true
		-- Position the clone relative to the hit part
		local snappedPos = Vector3.new(
			OnRound(hit.Position.X, grid),
			OnRound(hit.Position.Y, grid),
			OnRound(hit.Position.Z, grid)
		)
		clone.Position = snappedPos + Vector3.new(grid / 2, grid / 2, grid / 2)
	end
end)

This should snap the new part to the grid, with its position relative to the part that the mouse is hovering over.

Note that this solution may not work; it is just a suggestion for you to fix the code. I did not test those codes or methods before posting this. Feel free to reply to this thread and ask for more help if needed.

soo i need to first convert mouse position relative to the grid part position, then convert this relative position into snapped position, after that convert it to vvorld space and then i get result?

1 Like

Yes. Ask away if you need help, but I’d give it a try first.

i’m did this

local plr = game.Players.LocalPlayer

local mouse = plr:GetMouse()

local function OnSnap(n,m)
	return math.floor(n/m+0.5)*m
end

local function OnVector(Pos)
	local x 
	local y 
	local z 
	
	x = OnSnap(Pos.X,4)
	y = OnSnap(Pos.Y,4)
	z = OnSnap(Pos.Z,4)
	
	return Vector3.new(x,y,z)
end
local function OnAsync(cf: CFrame)
	
	local objectSpace = cf:ToObjectSpace(workspace.Part.CFrame)+ Vector3.new(0,workspace.Block.Size.Y/2,0)
	
	local relativeSnapped = OnVector(objectSpace)
	
	local CFr = CFrame.new(relativeSnapped)
	
	local world = CFr:ToWorldSpace(objectSpace)
	return world
	
end
mouse.Move:Connect(function()
	local relative = OnAsync(mouse.Hit)
	workspace.Block.Position = relative.Position
end)
	

it doesn’t vvorked and sorry i’m vvriting tvvo v because my key are broken

1 Like

Uhhh here’s an example.

local block = script.Block
block.Parent = game.Workspace

function snap(n: number, gridSize: number): number
	return math.floor(n/gridSize + 0.5) * gridSize
end

function snapV3(v: Vector3, gridSize: number): Vector3
	return Vector3.new(snap(v.X, gridSize), snap(v.Y, gridSize), snap(v.Z, gridSize))
end

function snapV3Relative(relativeTo: CFrame, v: Vector3, gridSize: number): Vector3
	local relativeV = relativeTo:PointToObjectSpace(v)
	local snappedV = snapV3(relativeV, gridSize)
	local unRelativeSnappedV = relativeTo:PointToWorldSpace(snappedV)
	return unRelativeSnappedV
end

function snapV3ToPart(relativeTo: BasePart, v: Vector3, gridSize: number): Vector3
	return snapV3Relative(relativeTo.CFrame, v, gridSize)
end

function withoutTranslation(cf: CFrame): CFrame
	return cf - cf.Position
end

local GRID_SIZE = 4
local mouse = game.Players.LocalPlayer:GetMouse()
mouse.TargetFilter = block
mouse.Move:Connect(function()
	local hit = mouse.Hit
	local target = mouse.Target
	if not target then return end
	block.CFrame = withoutTranslation(target.CFrame) + snapV3ToPart(target, hit.Position, GRID_SIZE)
end)

a:ToObjectSpace(b) does NOT convert a to the object space of b. It converts b to the object space of a. So

local objectSpace = workspace.Part.CFrame:ToObjectSpace(cf)

would be the way to convert the cf to the Parts object space. Or "cf relative to Part".

RIP letter 🇼 :sob:

2 Likes

it vvon’t vvork correctly, i’m tried using this script and inplementing it into mine and nothing

1 Like

Here’s a working place file:
Classic Baseplate.rbxl (30.9 KB)

Keep in mind there’s a lot more to a system like this than just grid snapping, but the place file does show how to do that at least

2 Likes

Thaanks, this is vvhat i’m looking for,i’m make some analysis about that, anyvvays thanks you and rip w

1 Like

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