How can I make a border of parts?

Simply, I want this:

To be become this:

I tested different solutions including this:

Non-working code
local function encaseface(part, offset, faceSize)
	part.Anchored = true
	part.Size = faceSize
	part.Position += offset
	part.Parent = workspace -- Parent to workspace or model
	return part
end

local function partencase(part)
	local size = part.Size
	local position = part.Position
	-- Top face (above the original part)
	encaseface(part, Vector3.new(0, size.Y / 2 + 0.5, 0), Vector3.new(size.X, 1, size.Z))
	-- Bottom face (below the original part)
	encaseface(part, Vector3.new(0, -size.Y / 2 - 0.5, 0), Vector3.new(size.X, 1, size.Z))
	-- Front face (in front of the original part)
	encaseface(part, Vector3.new(0, 0, size.Z / 2 + 0.5), Vector3.new(size.X, size.Y, 1))
	-- Back face (behind the original part)
	encaseface(part, Vector3.new(0, 0, -size.Z / 2 - 0.5), Vector3.new(size.X, size.Y, 1))
	-- Left face (left of the original part)
	encaseface(part, Vector3.new(-size.X / 2 - 0.5, 0, 0), Vector3.new(1, size.Y, size.Z))
	-- Right face (right of the original part)
	encaseface(part, Vector3.new(size.X / 2 + 0.5, 0, 0), Vector3.new(1, size.Y, size.Z))
end

local function encase(part: BasePart)
	local position = part.Position
	local size = part.Size
	
end

local testpart = Instance.new("Part")
testpart.Anchored = true
testpart.Parent = workspace
testpart:PivotTo(CFrame.new(0, 20, 0))
partencase(testpart)

I want a function that allows me to create a 3d border around the part and specify the thickness. Sadly, I haven’t been able to achieve this. Any help at all is appreciated!

This should hopefully be what you’re looking for ^^ (untested but in theory should work)

local function encase(part: BasePart, Thickness: number)
	assert(part, "Part must be defined.")
	assert(Thickness, "A thickness value must be defined.")

	local faces = {
		{Vector3.new(-1, 0, 0), Vector3.new(Thickness, part.Size.Y, part.Size.Z)}, -- Left
		{Vector3.new(1, 0, 0), Vector3.new(Thickness, part.Size.Y, part.Size.Z)},  -- Right
		{Vector3.new(0, -1, 0), Vector3.new(part.Size.X, Thickness, part.Size.Z)}, -- Bottom
		{Vector3.new(0, 1, 0), Vector3.new(part.Size.X, Thickness, part.Size.Z)},  -- Top
		{Vector3.new(0, 0, -1), Vector3.new(part.Size.X, part.Size.Y, Thickness)}, -- Front
		{Vector3.new(0, 0, 1), Vector3.new(part.Size.X, part.Size.Y, Thickness)}   -- Back
	}
	-- ^^^ Setting up all the faces we need for our specified part ^^^ --
	-- vvv Using our faces in a for loop in order to properly place our border pieces vvv ---
	for _, face in pairs(faces) do
		local facePosition, faceSize = face[1], face[2]
		local partFace = Instance.new("Part")
		partFace.Transparency = .5
		partFace.Material = Enum.Material.Neon
		partFace.Anchored = true
		partFace.CanCollide = false
		partFace.Size = faceSize
		partFace.CFrame = part.CFrame * CFrame.new(
			(part.Size.X/2 + faceSize.X/2) * facePosition.X, 
			(part.Size.Y/2 + faceSize.Y/2) * facePosition.Y, 
			(part.Size.Z/2 + faceSize.Z/2) * facePosition.Z
		)
		partFace.Parent = part
	end
end

encase(script.Parent,1)

Hi Tenny,
I was actually interested in trying this out myself, I had various troubles but have finally put together a working function in which you can also specify your thickness based on the second parameter of the function. Here’s a working and tested script.

function encase(targetPart, thickness)
	local size = targetPart.Size
	local position = targetPart.Position

	local faces = {
		front = Vector3.new(thickness, size.Y, size.Z),
		back = Vector3.new(thickness, size.Y, size.Z),
		left = Vector3.new(size.X, size.Y, thickness),
		right = Vector3.new(size.X, size.Y, thickness),
		top = Vector3.new(size.X, thickness, size.Z),
		bottom = Vector3.new(size.X, thickness, size.Z)
	}

	local function partencase(size, position)
		local borderPart = Instance.new("Part")
		borderPart.Anchored = true
		borderPart.Size = size
		borderPart.Position = position
		borderPart.Material = Enum.Material.SmoothPlastic
		borderPart.BrickColor = BrickColor.Red()
		borderPart.Transparency = 0.5
		borderPart.Parent = targetPart
	end

	partencase(faces.front, position + Vector3.new((size.X / 2) + (thickness / 2), 0, 0))
	partencase(faces.back, position - Vector3.new((size.X / 2) + (thickness / 2), 0, 0))
	partencase(faces.left, position - Vector3.new(0, 0, (size.Z / 2) + (thickness / 2)))
	partencase(faces.right, position + Vector3.new(0, 0, (size.Z / 2) + (thickness / 2)))
	partencase(faces.top, position + Vector3.new(0, (size.Y / 2) + (thickness / 2), 0))
	partencase(faces.bottom, position - Vector3.new(0, (size.Y / 2) + (thickness / 2), 0))
end

local Part = workspace:WaitForChild("Part")
encase(Part, 0.5)

Thanks guys! Both of your scripts made the part borders.

There was only one small difference in the result when I tested them

With @Dev_Ghostt’s script the rotation was unadjusted:

Whereas with @Triassiq’s script, it was adjusted:

Both of them technically passed the test using the two original parts, but I admit the rotation correction is nicest for my use

Thank you both for your help; I’ll analyze the code to understand the principles.

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