Wall Builder | Smoothening Algorithm

Hey all,

I have a click-and-drag wall builder but am in need of help getting the edges smoothed out and ideas on how to handle overlapping pieces. I will attach the place file for you to use - full code (it’s in the StarterPlayerScripts > gameCode > Classes > WallRender) Let me explain in two-step below.

Smoothening with Wedge Parts

The YouTube video below shows how it currently works and that non-straight segments are jagged. How can I (you don’t have to modify my code or look at it, but even linear ideas are welcome) properly insert a WedgePart into those corners rotated correctly?

Handling Overlapping Segments

Say I make a wall like below.

image

Then I place another next to it.

What sort of algorithm would you propose I use to determine when a wall gets placed next to it - or when the new wall is placed next to an existing wall - so I can then remove the original accent pieces that are on the edges?

All walls/buildings are in a grid (4x4 studs)

image

Place file for your leisure: stronghold.rbxl (57.0 KB)

1 Like

Solved the first problem (smoothening sharp corners with wedge parts). Shown below. Code solution also shown.

I check if the next wall piece being drag-built is on the same axis as the previous one (comparing the previous wall’s X and Z). Then, if they are both different, I get the direction to the next piece.

image

The red is the direction. Then I apply 2D vector rotation to get the yellow lines (which are 90 degrees from the original base). I place the wedges at those positions. I custom-create the rotation matrix to make sure the wedge faces the right place.

function WallRender.getWedgePiecesForSmoothening(base1, base2)
	local directionToBase2 = (base2.Position - base1.Position).unit
	local directionRotated45Deg = Vector3.new(
		directionToBase2.X * math.cos(math.pi/4) - directionToBase2.Z * math.sin(math.pi/4), 
		directionToBase2.Y,
		directionToBase2.X * math.sin(math.pi/4) + directionToBase2.Z * math.cos(math.pi/4)
	)
	local directionRotated45DegNegative = Vector3.new(
		directionToBase2.X * math.cos(-math.pi/4) - directionToBase2.Z * math.sin(-math.pi/4), 
		directionToBase2.Y,
		directionToBase2.X * math.sin(-math.pi/4) + directionToBase2.Z * math.cos(-math.pi/4)
	)
	
	local corner1Position = base1.Position + (directionRotated45Deg * WallRender.wallSquareSize) 
	local corner2Position = base1.Position + (directionRotated45DegNegative * WallRender.wallSquareSize)
	
	local corner1FacingBase1 = (base1.Position - corner1Position).unit
	local corner2FacingBase1 = (base1.Position - corner2Position).unit
	
	local matrixForCorner1 = CFrame.fromMatrix(
		Vector3.new(),
		Vector3.new(0,1,0),
		-corner1FacingBase1,
		corner1FacingBase1:Cross(Vector3.new(0,1,0))
	)
	local matrixForCorner2 = CFrame.fromMatrix(
		Vector3.new(),
		-Vector3.new(0,1,0),
		-corner2FacingBase1,
		corner2FacingBase1:Cross(-Vector3.new(0,1,0))
	)
	
	local cornerModel = Instance.new("Model")
	
	local corner1 = Instance.new("WedgePart")
	corner1.Size = Vector3.new(WallRender.wallHeight, WallRender.wallSquareSize, WallRender.wallSquareSize)
	corner1.Anchored = true
	corner1.Material = Enum.Material.Brick
	corner1.BrickColor = BrickColor.new("Fossil")
	corner1.CFrame = (CFrame.new(corner1Position) * matrixForCorner1) * CFrame.new(corner1.Size.X/2,0,0)
	corner1.Material = Enum.Material.Brick	
	
	local corner2 = Instance.new("WedgePart")
	corner2.Size = Vector3.new(WallRender.wallHeight, WallRender.wallSquareSize, WallRender.wallSquareSize)
	corner2.Anchored = true
	corner2.Material = Enum.Material.Brick
	corner2.BrickColor = BrickColor.new("Fossil")
	corner2.CFrame = (CFrame.new(corner2Position) * matrixForCorner2) * CFrame.new(-corner2.Size.X/2,0,0)
	corner2.Material = Enum.Material.Brick
	
	corner1.Parent = cornerModel
	corner2.Parent = cornerModel
	
	return cornerModel
end

you could use GetTouchingParts() and see if anything overlaps but I think that using CollectionService is highly bad for this case scenario so better stick with GetTouchingParts, returns an Array of Touching Parts

1 Like