Help with making a pyramid

Hi, I’ve been trying to make something that creates pyramids using corner wedge parts. 4 of these will make up a perfect pyramid, I’ve figured out how to position 2 of the 4 pieces, and I’ve been struggling with the 3rd and 4th pieces.

Here’s what I have so far:

local function findSurface(basePart, surface)
	local origin = basePart.Position;
	local size = basePart.Size;
	
	local x, z = size.X, size.Z;
	
	local P = {
		x0 = CFrame.new(origin) * CFrame.new(x * 0.5, 0, 0).p;
		y0 = CFrame.new(origin) * CFrame.new(0, 0, z * 0.5).p;
		x1 = CFrame.new(origin) * CFrame.new(-x * 0.5, 0, 0).p;
		y1 = CFrame.new(origin) * CFrame.new(0, 0, -z * 0.5).p;
	};
	
	return P[surface];
end;

local function createPyramid()
	local c1 = Instance.new("CornerWedgePart");
	c1.Anchored = true;
	c1.CanCollide = false;
	
	c1.Parent = workspace;
	
	local c2 = c1:Clone();
	c2.Anchored = true;
	c2.Position = findSurface(c1, "y0");
	c2.CFrame = c2.CFrame:Inverse() * CFrame.Angles(0, -math.rad(90), 0);
	c2.Position = c2.Position + Vector3.new(0, 0, -c1.Size.Z / 2)
	
	c2.Parent = workspace;
	
	local c3 = c1:Clone();
	c3.Anchored = true;
	c3.Position = findSurface(c2, "x0");
	c3.CFrame = c3.CFrame:Inverse() * CFrame.Angles(0, math.rad(180), 0);
	
	c3.Parent = workspace;
end;
3 Likes

I’ve been messing around with the script for a while, and I’ve gotten to something that sort of looks like a pyramid. It works when the size is set to something larger, however when the size is something like [1, 1, 1], the corner wedge parts are more spaced out making it look a lot less like a pyramid. If anybody knows how to fix this, please let me know.

local function findSurface(basePart, plane)
	local origin = basePart.Position;
	local size = basePart.Size;
	
	local x, z = size.X, size.Z;
	
	local P = {
		x0 = CFrame.new(origin) * CFrame.new(x * 0.5, 0, 0).p;
		y0 = CFrame.new(origin) * CFrame.new(0, 0, z * 0.5).p;
		x1 = CFrame.new(origin) * CFrame.new(-x * 0.5, 0, 0).p;
		y1 = CFrame.new(origin) * CFrame.new(0, 0, -z * 0.5).p;
	};
	
	return P[plane];
end;

local function createUnion(parts)
	local u = parts[1]:UnionAsync(parts);
	
	for _, part in ipairs(parts) do
		part:Destroy();
	end;
	
	return u;
end;

local function createCrystalTop(o, s)
	local s = s or 1;
	
	local c1 = Instance.new("CornerWedgePart");
	c1.Anchored = true;
	c1.Position = o or Vector3.new();
	c1.Size = Vector3.new(s, s, s);
	c1.CanCollide = false;
	
	c1.Parent = workspace;
	
	local c2 = c1:Clone();
	c2.Position = findSurface(c1, "y0");
	c2.CFrame = c2.CFrame:Inverse() * CFrame.Angles(0, -math.rad(90), 0);
	c2.Position = c2.Position + Vector3.new(0, 0, -c1.Size.Z / 2);
	
	c2.Parent = workspace;
	
	local u1 = createUnion{c1, c2};
	u1.Parent = workspace;
	
	local u2 = u1:Clone();
	u2.Position = findSurface(u1, "x0");
	u2.CFrame = u2.CFrame:Inverse() * CFrame.Angles(0, math.rad(180), 0);
	u2.Position = u1.Position + Vector3.new(u1.Size.X, 0, 0);
	
	u2.Parent = workspace;
	
	local finalUnion = createUnion{u1, u2};
	finalUnion.Parent = workspace;
end;

createCrystalTop(nil, 2);

I figured it would be easier to get the first 2 corners, turn it into a union and then turn it around.

How about this approach?

local offsets = {
	Vector3.new(-0.25, 0, 0.25),
	Vector3.new(0.25, 0, 0.25),
	Vector3.new(0.25, 0, -0.25),
	Vector3.new(-0.25, 0, -0.25),
}

local function createPyramid(center, size)
	local model = Instance.new("Model")
	for i = 1, 4 do
		local wedge = Instance.new("CornerWedgePart")
		
		if i%2 == 0 then
			wedge.Size = Vector3.new(size.Z / 2, size.Y, size.X / 2)
		else
			wedge.Size = Vector3.new(size.X / 2, size.Y, size.Z / 2)
		end
		
		wedge.CFrame = CFrame.new(center + offsets[i]*size) * CFrame.Angles(0, (i-1)*math.pi/2, 0)
		wedge.Anchored = true
		wedge.Parent = model
	end
	return model
end

-- usage example

local center = Vector3.new(0, 3, 0)
local size = Vector3.new(10, 4, 6)

local p = createPyramid(center, size)
p.Parent = workspace
2 Likes

Thanks, this works perfectly, I’ve been struggling with these pyramids for hours :smiley:

1 Like