Here's something that works well:
– Return a list of points evenly spaced in a right-angle grid in a unit cube (1x1x1)
– (resolution + 1) points will be generated along each axis, to divide the unit cube into
– (resolution) number of smaller cubes.
– resolution is a Vector3, where each component represents the resolution in the respective axis.
function makeUnitCubeVolumeGrid(resolution)
local points = {}
for posX = 0, 1, 1 / resolution.X do
for posY = 0, 1, 1 / resolution.Y do
for posZ = 0, 1, 1 / resolution.Z do
table.insert(points, Vector3.new(posX, posY, posZ))
end
end
end
return points
end
– Return a list of points evenly spaced in a right-angle grid on the surface of a unit cube (1x1x1)
– (resolution + 1) points will be generated along each axis, to divide the unit cube into
– (resolution) number of smaller cubes.
– resolution is a Vector3, where each component represents the resolution in the respective axis.
function makeUnitCubeSurfaceGrid(resolution)
local points = {}
--Not the most efficient algo, but probably not performance critical so worth it in dev time
for posX = 0, 1, 1 / resolution.X do
for posY = 0, 1, 1 / resolution.Y do
for posZ = 0, 1, 1 / resolution.Z do
if posX == 0 or posX == 1 or posY == 0 or posY == 1 or posZ == 0 or posZ == 1 then
table.insert(points, Vector3.new(posX, posY, posZ))
end
end
end
end
return points
end
–Given a point, return the point translated according to the position
– of a part and a given anchorpoint, and scaled and rotated according
– to the size and orientation of the part, respectively.
function transformPointToPartSpace(point, part, anchorPoint)
return part.CFrame:PointToWorldSpace(
(point + anchorPoint) * part.Size
)
end
– Given a list of values v1 … vn, a function f, and values …,
– return a list containing f(v1, …) … f(vn, …)
function map(list, f, …)
local result = {}
for _, v in pairs(list) do
table.insert(result, f(v, …))
end
return result
end
function makePartAttachmentGrid(part, gridResolution, isSurfaceGrid)
local attachments = {}
--gridResolution can be a Vector3 to have different resolutions on each axis,
-- or a number to have the same resolution on each axis.
local resolutionVector = typeof(gridResolution) == "Vector3"
and gridResolution
or Vector3.new(1, 1, 1) * gridResolution
--Attachments can be spaced around the surface or the volume (default) of the part
local gridPoints = isSurfaceGrid
and makeUnitCubeSurfaceGrid(resolutionVector)
or makeUnitCubeVolumeGrid(resolutionVector)
local transformedPoints = map(gridPoints, transformPointToPartSpace, part, Vector3.new(-0.5, -0.5, -0.5))
for _, transformedPoint in ipairs(transformedPoints) do
local attachment = Instance.new("Attachment")
attachment.CFrame = CFrame.new(transformedPoint - game.Workspace.Part.Position)
attachment.Parent = game.Workspace.Part
table.insert(attachments, attachment)
end
return attachments
end
makePartAttachmentGrid(game.Workspace.Part, 8, true)
I modified some of my old code to work with the “surface” grid thing. Hope it helps! If you’ve any questions then ask away