Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Generating a grid based on a part starting at the top left corner?

#Problem:# So I have a part that is sized so that a grid can be generated based on that 1 part's position and size. The issue is the grid loading is off and I would like to know how I could fix it. I would like it so that the 4x4 cubes fill up the entire square. I would like to say beforehand that this script wasn't created from scratch by me.The The grid is supposed to overlap the highlighted part

#Square Image:# https://gyazo.com/e80576797183b946645273288decda29 https://gyazo.com/bbe42eb307d331cf07bface16f9cf845

#Script:#

local function PlaceMarker(v3)
	local p = Instance.new("Part")
	p.CFrame = CFrame.new(v3)
	p.Size = Vector3.new(1, 1, 1)
	p.Anchored = true
	p.CanCollide = false
	p.Color = Color3.new(1, 0, 0)
	p.Material = Enum.Material.Neon
	p.Parent = workspace
end

local function CreateGridFromBase(base, gridSize)
	local px, py, pz, sx, sz = base.Position.X, base.Position.Y, base.Position.Z, base.Size.X, base.Size.Z
	px, pz = px - sx / 2, pz - sx / 2
	local rotCFrame = base.CFrame - base.CFrame.p
	local gridParts = Instance.new("Folder")
	gridParts.Name = "GridParts"
	print(px - sx / 2, px + sx / 2, pz - sz / 2, pz + sz / 2)
	PlaceMarker(Vector3.new(px - sx / 2, py, pz - sz / 2))
	PlaceMarker(Vector3.new(px + sx / 2, py, pz + sz / 2))
	for x = px - sx / 2, px + sx / 2, gridSize do
		for z = pz - sz / 2, pz + sz / 2, gridSize do
			local p = Instance.new("Part")
			p.Anchored = true
			p.CanCollide = false
			p.Transparency = 1
			p.CFrame = CFrame.new(x, py+0.05, z)
			p.Size = Vector3.new(gridSize, 1, gridSize)
			p.Parent = gridParts
		end
	end
	gridParts.Parent = base
	return gridParts
end

NOTE The size of the square was sized so that it would dividable by 4.

Thank you for attempting to assist me!

BlackOrange3343 ~ I'm bad at math.

1 answer

✓ Accepted answer

I ended up rewriting it because it was easier than deciphering what the original was trying to do - the lesson here is probably to spend longer writing something to make sure it's readable.

--[[
    Generic function to create a part, with customProperties parameter to
    specialise it.
    
    Avoids code duplication in placeMarker and placeGrid functions

    position: Vector3 -> Where to place the new part, and how to turn it
    parent: Instance -> What to parent the new part to
    customProperties: Table<String, Any> -> A dictionary of custom properties
        which will be applied to the part. Index is the property name, and
        value is the value to assign to the chosen property.
]]
function placePart(position, parent, customProperties)
    local p = Instance.new("Part")
    for property, value in pairs(customProperties) do
        p[property] = value
    end
    p.CFrame = position
    p.Anchored = true
    p.CanCollide = false
    p.Color = Color3.new(1, 0, 0)
    p.Parent = parent
end


--[[
    Creates a marker at the given position

    position: CFrame -> Where to place the marker, and how to turn it
]]
function placeMarker(position)
    placePart(position, workspace, {
        ["Material"] = Enum.Material.Neon,
        ["Size"] = Vector3.new(1, 1, 1)
    })
end


--[[
    Creates a grid piece at the given position, with the given parent.

    position: CFrame -> Where to create the grid part, and how to turn it
    parent: Instance -> What to parent the grid part to
    gridSize: Numeric -> The size of the grid piece in studs
]]
function placeGrid(position, parent, gridSize)
    placePart(position, parent, {
        ["Transparency"] = 0.5,
        ["Size"] = Vector3.new(gridSize, 1, gridSize)
    })
end


--[[
    Creates a grid-like structure of blocks covering the base. Assumes the
    base has a Size.y of 1.

    If gridSize doesn't divide the base cleanly, there will be spill-over at
    the edges, rather than the grid stopping short.

    base: Part -> The block to create the grid on top of
    gridSize: Numeric -> The size of the grid cells to create
]]
function createGridFromBase(base, gridSize)
    local position = base.CFrame
    local size = base.Size
    local topLeft = position * CFrame.new(-size.x/2, 0, -size.z/2)
    local cellOffset = CFrame.new(gridSize / 2, 0, gridSize / 2)
    placeMarker(topLeft, workspace)
    -- Keep track of position outside the loop so we can retrieve it at the
    --     end to set the final marker
    local pos
    for x = 0, size.x, gridSize do
        for z = 0, size.z, gridSize do
            pos = topLeft * CFrame.new(x, 0, z) * cellOffset
            placeGrid(pos, script.Parent, gridSize)
        end
    end
    -- Set the final marker
    placeMarker(pos * cellOffset, workspace)
end


createGridFromBase(script.Parent, 3.5)

This discussion is preserved as it was. New answers, comments, and votes are closed.