Making A Grid System

local rep = game:GetService("ReplicatedStorage")
local placeObj = rep:WaitForChild("remotes"):WaitForChild("placeObj")
local objects = rep:WaitForChild("objects")

local uis = game:GetService("UserInputService")
local runServ = game:GetService("RunService")

local plr = game.Players.LocalPlayer
local char = plr.Character or plr.Character:Wait()
local humanoidRootPart = char:WaitForChild("HumanoidRootPart")
local mouse = plr:GetMouse()
local objFrame = script.Parent.invFrame

local yBuildingOffset = 2.5 -- change this to the parts height / 2 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
local maxPlacingDistance = 50
local rKeyIsPressed = false
local placingObj = false

for i, objButton in pairs(objFrame:GetChildren()) do
	if objButton:IsA("TextButton") or objButton:IsA("ImageButton") then
		objButton.MouseButton1Up:Connect(function()
			local yOrientation = 0
			local goodToPlace = false
			local placedObj

			if placingObj == false then
				placingObj = true

				local clientObj = objects:FindFirstChild("item"):Clone() -- CHANGE THIS LATER aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
				clientObj.BrickColor = BrickColor.new("Forest green")
				clientObj.Material = "Neon"
				clientObj.CanCollide = false
				clientObj.Parent = game.Workspace

				local startingCFrame = CFrame.new(0, -2, -15)
				clientObj.CFrame = humanoidRootPart.CFrame:ToWorldSpace(startingCFrame)

				runServ.RenderStepped:Connect(function()
					local mouseRay = mouse.UnitRay
					local castRay = Ray.new(mouseRay.Origin, mouseRay.Direction * 1000)
					local ignoreList = {clientObj, char}
					local hit, position = workspace:FindPartOnRayWithIgnoreList(castRay, ignoreList)

					if hit and (--[[hit:IsA("Part")--]] hit.Name == "Baseplate") and (humanoidRootPart.Position - clientObj.Position).Magnitude < maxPlacingDistance then
						goodToPlace = true
						clientObj.BrickColor = BrickColor.new("Forest green")
					else
						goodToPlace = false
						clientObj.BrickColor = BrickColor.new("Crimson")
					end

					local newAnglesCFrame = CFrame.Angles(0, math.rad(yOrientation), 0)
					local newCFrame = CFrame.new(position.X, position.Y + yBuildingOffset, position.Z)
					clientObj.CFrame = newCFrame * newAnglesCFrame
				end)

				uis.InputBegan:Connect(function(input)
					if input.KeyCode == Enum.KeyCode.R then
						rKeyIsPressed = true

						local rotationSpeed = 5
						while rKeyIsPressed do
							wait()
							if placingObj == true then
								yOrientation = yOrientation + rotationSpeed
							end
						end
					end
				end)

				uis.InputEnded:Connect(function(input)
					if input.KeyCode == Enum.KeyCode.R then
						rKeyIsPressed = false
					end
				end)

				uis.InputBegan:Connect(function(input)
					if input.UserInputType == Enum.UserInputType.MouseButton1 then
						if placingObj == true then
							if goodToPlace == true then
								local objCFrame = clientObj.CFrame
								placedObj = placeObj:InvokeServer(clientObj.Name, objCFrame)

								if placedObj == true then
									placingObj = false
									clientObj:Destroy()
								end
							end
						end
					end
				end)
			end
		end)
	end
end

Here is my script for a placement system in roblox

What are you trying to achieve?:
I want to make it go in a grid system but it has been bugging and the methods I used never worked. It is currently a free placing system so theres no grid.

I hope i understand what you are requesting, should be fairly simple. Just make a function to round to the nearest multiple of what size of grid you want

local function snapToGrid(position)
	local snappedX = math.floor(position.X / gridSize + 0.5) * gridSize
	local snappedY = math.floor(position.Y / gridSize + 0.5) * gridSize
	local snappedZ = math.floor(position.Z / gridSize + 0.5) * gridSize
	return Vector3.new(snappedX, snappedY, snappedZ)
end

And when setting the cframe of the object on the client, simply use the function with the position you got from the the raycast

				local snappedPosition = snapToGrid(position)
				local newAnglesCFrame = CFrame.Angles(0, math.rad(yOrientation), 0)
				local newCFrame = CFrame.new(snappedPosition.X, snappedPosition.Y + yBuildingOffset, snappedPosition.Z)
				clientObj.CFrame = newCFrame * newAnglesCFrame

Works like a charm

1 Like

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