Grid placement system

I need help with the grid placement system. Current issue is that when position snaps to grid it actually goes bit off the plot. So what I want is to somehow calculate position inside of the plot so every grid size should stay inside of plot.

image

code:

local sys = {}
local effects = require(script.Parent.Effects)

sys.GridSize = 4
sys.Plot = workspace.Plots.Plot.Plot
sys.GridTable = {sys.Plot}
sys.Rotation = 45
sys.CurRotation = 0
sys.SelModel = workspace.ThatModel
sys.Cords = nil

function sys:Update(thing,value)
	self[thing] = value
end

function sys:Snap(mouse)
	local X = math.floor(mouse.Hit.p.X / self.GridSize + 0.5) * self.GridSize
	--local Y = math.floor(mouse.Hit.p.Y / self.GridSize + 0.5) * self.GridSize
	local Z = math.floor(mouse.Hit.p.Z / self.GridSize + 0.5) * self.GridSize
	return X,Z
end

--[[
function sys:Snap(o)
	local X = math.floor(o.X / self.GridSize + 0.5) * self.GridSize
	local Z = math.floor(o.Z / self.GridSize + 0.5) * self.GridSize
	return X,Z
end
]]

function sys:NRay(mouse,char)
	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Whitelist
	params.FilterDescendantsInstances = self.GridTable
	local cast = workspace:Raycast(self.SelModel.PrimaryPart.Position,(mouse.Hit.p - self.SelModel.PrimaryPart.Position),params)
	return cast
end

function sys:Move(mouse,char)
	mouse.TargetFilter = self.SelModel
	local check = self:NRay(mouse,char)
	--print(check.Position)
	if check ~= nil then
		local x,z = self:Snap(mouse)
		--sys.SelModel.PrimaryPart.CFrame = CFrame.new(Vector3.new(x,2,z)) * CFrame.Angles(0,math.rad(self.CurRotation),0)
		local tween = effects:MoveTween(self.SelModel,{CFrame = CFrame.new(Vector3.new(x,self.Plot.Position.Y+1,z)) * CFrame.Angles(0,math.rad(self.CurRotation),0)})
		tween:Play()
		self.Cords = CFrame.new(Vector3.new(x,self.Plot.Position.Y+1,z)) * CFrame.Angles(0,math.rad(self.CurRotation),0)
	end
	--sys.SelModel.PrimaryPart.CFrame = CFrame.new(Vector3.new(x,2,z)) * CFrame.Angles(0,math.rad(self.CurRotation),0)
end

function sys:Place()
	game.ReplicatedStorage.Remotes.Place:FireServer(self.SelModel.Name,self.Cords)
end

return sys

Yes, you can either try changing the grid’s position or just add an offset which would be half the grid size on the x and z axis in the snap function

could you provide an example please I’m not sure that I got this offset part right.

local sys = {}
local effects = require(script.Parent.Effects)

sys.GridSize = 4
sys.Plot = workspace.Plots.Plot.Plot
sys.GridTable = {sys.Plot}
sys.Rotation = 45
sys.CurRotation = 0
sys.SelModel = workspace.ThatModel
sys.Cords = nil

function sys:Update(thing,value)
	self[thing] = value
end

function sys:Snap(mouse)
	local X = math.floor(mouse.Hit.p.X / self.GridSize + 0.5) * self.GridSize
	--local Y = math.floor(mouse.Hit.p.Y / self.GridSize + 0.5) * self.GridSize
	local Z = math.floor(mouse.Hit.p.Z / self.GridSize + 0.5) * self.GridSize
	return X,Z
end

--[[
function sys:Snap(o)
	local X = math.floor(o.X / self.GridSize + 0.5) * self.GridSize + self.GridSize / 2
	local Z = math.floor(o.Z / self.GridSize + 0.5) * self.GridSize + self.GridSize / 2
	return X,Z
end
]]

function sys:NRay(mouse,char)
	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Whitelist
	params.FilterDescendantsInstances = self.GridTable
	local cast = workspace:Raycast(self.SelModel.PrimaryPart.Position,(mouse.Hit.p - self.SelModel.PrimaryPart.Position),params)
	return cast
end

function sys:Move(mouse,char)
	mouse.TargetFilter = self.SelModel
	local check = self:NRay(mouse,char)
	--print(check.Position)
	if check ~= nil then
		local x,z = self:Snap(mouse)
		--sys.SelModel.PrimaryPart.CFrame = CFrame.new(Vector3.new(x,2,z)) * CFrame.Angles(0,math.rad(self.CurRotation),0)
		local tween = effects:MoveTween(self.SelModel,{CFrame = CFrame.new(Vector3.new(x,self.Plot.Position.Y+1,z)) * CFrame.Angles(0,math.rad(self.CurRotation),0)})
		tween:Play()
		self.Cords = CFrame.new(Vector3.new(x,self.Plot.Position.Y+1,z)) * CFrame.Angles(0,math.rad(self.CurRotation),0)
	end
	--sys.SelModel.PrimaryPart.CFrame = CFrame.new(Vector3.new(x,2,z)) * CFrame.Angles(0,math.rad(self.CurRotation),0)
end

function sys:Place()
	game.ReplicatedStorage.Remotes.Place:FireServer(self.SelModel.Name,self.Cords)
end

return sys
1 Like

function sys:Snap(mouse)
	local X = math.floor(mouse.Hit.p.X / self.GridSize + 0.5) * self.GridSize + self.GridSize / 2
	--local Y = math.floor(mouse.Hit.p.Y / self.GridSize + 0.5) * self.GridSize
	local Z = math.floor(mouse.Hit.p.Z / self.GridSize + 0.5) * self.GridSize + self.GridSize / 2
	return X,Z
end

This did not help me sorry. Thank you for replying.

1 Like

How about just decrease the size of the plots in the script by the width of 1 of your placed items?
You would place the plots in exactly the same way, but have it so the script would recognize that you would have 1 less item ‘width’ to place on them.

I don’t think that this fixes the issue. Issue is that part snaps/moves to closest position to mouse so if mouse is on edge of the plot and lets say grid size is 2 it will be half on the plot and half outside of it

But if you decrease the overall size of the placement plot by 1 grid and place it at the same location you are reducing the extra half on either side and making the placement system work to the outer edge.
Right now if you have a 10x10 plot you are placing items to the edge of it and getting 11x11 items.
Make your plot 9x9 and you’ll get your 10x10 grid of placed items.
It’s caused by you placing items at 0, 1, 2, 3…7, 8, & 9 hence 10 items.