Filling gaps (like starvants plugin) but live in game

So the wall is stored once for each of its polls. Each poll will have at least once wall attached to it, possibly more depending on if a user attaches another wall to it later. Does that clear things up? I wasn’t quite sure where you got two walls and two polls from.

The 2 poles are 1 pole each side of the wall.

The ‘wall’ itself is made up of 2 parts, Wall1, Wall2, which basically allows players to color the wall on each side differently.

I think tho, there’s a hitbox, which contains the entirity of the size of the wall, I could store that instead?

How were you able to get the code from the plugin??

You need enough information to resize the wall to accommodate future connections, however you choose to do so.

Not entirely sure if this is allowed, so flag it if it isn’t or please PM me so I know!

Download the plugin > go to %localappdata% > Roblox > InstalledPlugins > Get the plugin ID RBX file

What did you open the file with? I used notepad and it just has all this jibberish in it

Ended up doing it a little differently, but seems to get sort of a start

local function getAdditionalLength(angleBetweenWalls)
    return math.sin(angleBetweenWalls / 2) * 0.5 / 2
end

local function getAngle(wallDirA, wallDirB)
    math.acos(wallDirA.Unit:Dot(wallDirB.Unit))
end

local function checkPreviousPoles(poles, wall, pole1, pole2)
	for _, v in pairs(poles:GetChildren()) do
		if v.CFrame == pole1.CFrame or v.CFrame == pole2.CFrame then
			local Angle = getAngle('Somehow find out which 2 walls need resizing?')
			getAdditionalLength(Angle)
			print('Done')
		end
	end
end

checkPreviousPoles(walls.Poles, Wall, Pole1, Pole2) -- Wall is the model, which contains the 2 wall parts

So basically, it is printing when a pole is placed where a previous poles position is. Now, not sure how to include the code to referenced in your first reply.

More context - Each Pole (Pole1 and Pole2) have an ObjectValue inside of them, which has its Value set to whatever wall the said Pole belongs too, that way in the checkPreviousPoles function, you should be able to do pole1.ObjectValue.Value or pole2.ObjectValue.Value to see which wall these poles are connected to. Then using Wall.Wall1 and Wall.Wall2, can resize the 2 newer walls.

Not sure how to implement that tho?

You are already looping to move the object, check the edges are compare them to the other walls. Within a radius create them to snap onto the wall.

So you find the closest edge, and align your part’s position and rotation accordingly.

Now this is an extremely rough method and example, but one that could/should work.

(Think of it like rotating from the edge of the part… that specific face/anchor point.)

Little confused?? I’m not trying to move the object, just tryna resize it on one side to match with other walls placed

I was suggesting to instead allow the walls to snap onto each other and rotate off each other. You could create a pole to fill the gap between the two and make really smooth walls.

Also, you’d need to resize both walls to get it to match for things like rotations.

If you are at all interested in the method I am suggesting these might be of use;

Rotate a part off it’s own edge

Rotate a part off another part’s edge

That’s not what I’m after. I want the 2 parts to connect to each other, not rotate around each other.

You have to insert the plugin file into a place file, not open it in an IDE or notepad.

1 Like

Still haven’t got a solid answer :confused:

This should be about all of the core code. You’ll need to debug it, make it FE ready, integrate it with your UI, and set the constants in it though.

local wallModel = game.ReplicatedStorage.Wall

local WALL_HEIGHT = 5
local WALL_OFFSET = Vector3.new(0, WALL_HEIGHT, 0)
local UP = Vector3.new(0, 1, 0)

local function getAdditionalLength(angleBetweenWalls)
    return math.sin(angleBetweenWalls / 2) * 0.5 / 2
end

local function getAngle(wallDirA, wallDirB)
    math.acos(wallDirA:Dot(wallDirB))
end

local function snapToGrid(pos)
	return Vector3.new(
		math.floor(pos.X + 0.5),
		math.floor(pos.Y + 0.5),
		math.floor(pos.Z + 0.5)
	)
end

local abs = math.abs
local function absVector3(v3)
	return Vector3.new(
		abs(v3.X),
		abs(v3.Y),
		abs(v3.Z)
	)
end

local function adjust(wall, newLength)
	local delta = newLength - wall.length
	local offset = wall.Model.CFrame:ToObjectSpace(wall.dir) * delta
	wall.model.Size = wall.model.Size + absVector3(offset)
	wall.model.CFrame = wall.model.CFrame + offset / 2
	wall.length = newLength
end

local POLL_KEY = '%d %d %d'
local function getWalls(polls, pos)
	local key = POLL_KEY:format(pos.X, pos.Y, pos.Z)
	local walls = polls[key]
	if not walls then
		walls = {}
		polls[key] = walls
	end
	return walls
end

local function addToPoll(polls, poll, otherPoll, model)
	local walls = getWalls(polls, poll)
	local maxLength = 0
	local dir = (otherPoll - poll).Unit
	local wall = {
		length = maxLength;
		model = model;
		dir = dir;
	}

	for otherWall in next, walls do
		local length = getAdditionalLength(getAngle(dir, otherWall.dir))
		if length > maxLength then
			maxLength = length
		end
		if length > otherWall.length then
			adjust(otherWall, length)
		end
	end
	adjust(wall, maxLength)

	walls[wall] = true
end

local function placeWall(polls)
	local mouse = game.Players.LocalPlayer:GetMouse()

	mouse.Button1Down:Wait()
	local pollA = snapToGrid(mouse.Hit.p)

	mouse.Button1Down:Wait()
	local pollB = snapToGrid(mouse.Hit.p)

	local model = wallModel:Clone()
	model:SetPrimaryPartCFrame(CFrame.fromMatrix(
		(pollA + pollB) / 2 + WALL_OFFSET,
		(pollA - pollB).Unit,
		UP
	))

	addToPoll(polls, pollA, pollB, model)
	addToPoll(polls, pollB, pollA, model)
end

I figured that for multiple walls being placed on the same poll, each wall needs to adjust its length to the largest adjustment required for its angle to each other wall. If two walls are placed at 90 degrees to each other then both will extend 1 stud. If a third wall is then placed so that it is 135 degrees from each wall, then the other two walls will stay extended by 1 stud and the third will be extended sine of 135 degrees which is the same as sine of 45 degrees which is sqrt(2)/2. The result will be perfect corners all around.

Ok, tryna implement this with my code I already have (everything I have mentioned in previous posts has all been server side code)

local Wall = Instance.new('Model')
	Wall.Name = 'Wall'
				
	local Hitbox = Instance.new('Part', Wall)
	Hitbox.Material = Enum.Material.SmoothPlastic
	Hitbox.Transparency = 1
	Hitbox.Name = 'Hitbox'
	Hitbox.Anchored = true
	
	local Pole1 = createPole(Wall, 'Pole1', pole1CFrame)
	local Pole2 = createPole(Wall, 'Pole2', pole2CFrame)
	
	Hitbox.Size = Vector3.new((Pole1.Position - Pole2.Position).Magnitude, 12, 0.4)
	Hitbox.CFrame = CFrame.new(
		Pole1.Position + 0.5 * (Pole2.Position - Pole1.Position),
		Pole1.Position + 0.5 * (Pole2.Position - Pole1.Position) + (Pole1.Position - Pole2.Position).Unit:Cross(Vector3.new(0, 1, 0))
	)
	
	local WallPart1 = createWall('Wall1', Hitbox, 0.1)
	WallPart1.Parent = Wall
	
	local WallPart2 = createWall('Wall2', Hitbox, -0.1)
	WallPart2.Parent = Wall
	
	Hitbox.Size = Vector3.new((Pole1.Position - Pole2.Position).Magnitude, 12, 0.3)
		
	Pole1.Parent = walls.Poles
	Pole2.Parent = walls.Poles
	
	Wall.PrimaryPart = Hitbox
	Wall.Parent = walls

	addToPoll(walls.Poles, Pole1.Position, Pole2.Position, Wall)
	addToPoll(walls.Poles, Pole2.Position, Pole1.Position, Wall)
end

I get an error below here

local POLL_KEY = '%d %d %d'
local function getWalls(polls, pos)
	local key = POLL_KEY:format(pos.X, pos.Y, pos.Z)
	local walls = polls[key] -- error here
	if not walls then
		walls = {}
		polls[key] = walls
	end
	return walls
end

local function addToPoll(polls, poll, otherPoll, model)
	local walls = getWalls(polls, poll)
	local maxLength = 0
	local dir = (otherPoll - poll).Unit
	local wall = {
		length = maxLength;
		model = model;
		dir = dir;
	}

	for otherWall in next, walls do
		local length = getAdditionalLength(getAngle(dir, otherWall.dir))
		if length > maxLength then
			maxLength = length
		end
		if length > otherWall.length then
			adjust(otherWall, length)
		end
	end
	adjust(wall, maxLength)

	walls[wall] = true
end

Error
[-110 12 40 is not a valid member of Folder]

Since I’m not using your SnapToGrid function (as they are snapped on the client side when placing)

Since that function returns a Vector3, means I passed the Poles as Pole1.Position, instead of the Vector return, which should work right?
addToPoll(walls.Poles, Pole1.Position, Pole2.Position, Wall)

Yup, but the polls argument of the placeWall function is a table. It should start empty and as walls are placed the code will add polls to it. If you want global snapping (snapping to other player’s walls) then you can share this table for every player. For team snapping, have one polls table per a team. Likewise for player only snapping.

Ahh ok, well added that. Problem that’s just arrisen tho, is your code only scales if the model has 1 wall. Each wall model has 2 walls in it, like so


So there are 2 parts inside each wall, creating 2 sides to a wall

Just add the size and change the position of both the wall parts by the same amount. That will be the same as resizing one wall that spanned both of those parts, if that makes sense.

How would I get the code to know which walls to resize tho?

local function adjust(wall, newLength)
	local delta = newLength - wall.length
	local offset = wall.Model.CFrame:ToObjectSpace(wall.dir) * delta -- get an error here
	wall.model.Size = wall.model.Size + absVector3(offset)
	wall.model.CFrame = wall.model.CFrame + offset / 2
	wall.length = newLength
end

[attempt to index field ‘Model’ (a nil value)]

since wall’s children are

Hitbox
Wall1
Wall2

The Hitbox cannot be resized, it has to stay at an even number. But Wall1 and Wall2 can be resized, however, only 1 would have to be resized