Creating a floor building system

Hey, so I am currently working on a building system similar to the one found on Bloxburg.
This is what I have made so far:

The problem I currently have is how would I go about creating a floor building system where I can place 3 or more points on the ground and a floor would be placed according to those points?

This is currently how my floor placement works:
https://gyazo.com/a944b5d727b104ca3c55d309dfab59f5.gif

As you can see my system can only create floors from two points for each corner. This means I can only create square-shaped floors.

I saw a post showing something similar to my building system and it shows the floor placement system that I have in mind:

Would anyone know how I could make this?

Thanks in advance!

20 Likes

I think Region3 would be best way correct me if I am wrong.

I am not a good programmer or even been good soon but here is a simple script that I’ve made for you

local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()

local FirstLocation
local MouseDown = false
local Part

Mouse.Button1Down:Connect(function()
	MouseDown = true
	local X,Y,Z = math.floor(Mouse.Hit.X + 0.5),math.floor(Mouse.Hit.Y + 0.5),math.floor(Mouse.Hit.Z + 0.5)
	
	FirstLocation = Vector3.new(X,Y,Z)
	
	Part = Instance.new("Part")
end)

Mouse.Button1Up:Connect(function()
	MouseDown = false
	if (Part) then
		Part:Destroy()
	end
end)

Mouse.Move:Connect(function()
	if not(MouseDown) then
		return
	end
	local X,Y,Z = math.floor(Mouse.Hit.X + 0.5),math.floor(Mouse.Hit.Y + 0.5),math.floor(Mouse.Hit.Z + 0.5)
	
	local Region = Region3.new(FirstLocation,Vector3.new(X,Y,Z))
	
	Part.CFrame = Region.CFrame
	Part.Size = Region.Size
	Part.Parent = workspace
end)

I will be still scripting this and I’ll update you.

Update 2

local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()
local FloorPlacingModel = script.Floor
local FirstLocation
local MouseDown = false
local Part

Mouse.Button1Down:Connect(function()
	MouseDown = true
	local X,Y,Z = math.floor(Mouse.Hit.X + 0.5),math.floor(Mouse.Hit.Y + 0.5),math.floor(Mouse.Hit.Z + 0.5)
	
	FirstLocation = Vector3.new(X,Y,Z)
	
	Part = Instance.new("Part")
	Part.Anchored = true
end)

Mouse.Button1Up:Connect(function()
	MouseDown = false
	if (Part) then
		Part.Parent = workspace
		Part.Transparency = 0
		FloorPlacingModel.Parent = script
		local Part
	end
end)

Mouse.Move:Connect(function()
	local X,Y,Z = math.floor(Mouse.Hit.X + 0.5),math.floor(Mouse.Hit.Y + 0.5),math.floor(Mouse.Hit.Z + 0.5)
	FloorPlacingModel.Parent = workspace
	FloorPlacingModel.Position = Vector3.new(X,Y,Z)
	
	if not(MouseDown) then
		return
	end
	
	local Region = Region3.new(FirstLocation,Vector3.new(X,Y,Z))
	
	if (Region.Size.X < 0 or Region.Size.Z < 0) then
		Region = Region3.new(Vector3.new(X,Y,Z),FirstLocation)
	elseif (Region.Size.X < 0 and Region.Size.Z > 0) then
		--I dont know what to type here
	elseif (Region.Size.X > 0 and Region.Size.Z < 0) then	
		--I dont know what to type here
	end
	Mouse.TargetFilter = FloorPlacingModel
	FloorPlacingModel.Parent = workspace
	FloorPlacingModel.Position = Vector3.new(X,Y,Z)
	Part.CFrame = Region.CFrame
	Part.Size = Region.Size
	Part.Parent = workspace
end)
4 Likes

I have already created the system where I can place square-shaped floors on the ground, as seen in the first 2 gifs in my post. What I am looking for is an entirely different floor placement system where i can create non square shaped floors by placing down points for the corners of the floor.

Check out the youtube video in the main post at around 0:11 onward. You will be able to see what I’m talking about.

Ok I’ll do some testing and I’ll update you.

1 Like
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()
local Workspace = game:GetService("Workspace")
local Points = {}
local Color = BrickColor.new("Medium stone grey")
local Material = Enum.Material.SmoothPlastic
local Align = "Normal"
local Thickness = 1
local Tris = {}

function spawnTrianglePart(col,mat)
	local P = Instance.new("WedgePart")
	P.Anchored = true
	P.Parent = Workspace
	P.BrickColor = col
	P.Material = mat
	P.FrontSurface = Enum.SurfaceType.SmoothNoOutlines
	P.BackSurface = Enum.SurfaceType.SmoothNoOutlines
	P.LeftSurface = Enum.SurfaceType.SmoothNoOutlines
	P.RightSurface = Enum.SurfaceType.SmoothNoOutlines
	P.TopSurface = Enum.SurfaceType.SmoothNoOutlines
	P.BottomSurface = Enum.SurfaceType.SmoothNoOutlines
	return P
end	


function drawTriangle(a,b,c,n,ad)
	local len_AB = (b - a).magnitude
	local len_BC = (c - b).magnitude
	local len_CA = (a - c).magnitude

	if (len_AB > len_BC) and (len_AB > len_CA) then
		a,c = c,a
		b,c = c,b
	elseif (len_CA > len_AB) and (len_CA > len_BC) then
		a,b = b,a
		b,c = c,b
	end

	local dot = (a - b):Dot(c - b)
	local split = b + (c-b).unit*dot/(c - b).magnitude

	local xA = ad[3]
	local yA = (split - a).magnitude
	local zA = (split - b).magnitude

	local xB = ad[3]
	local yB = (split - a).magnitude
	local zB = (split - c).magnitude

	local diry = (a - split).unit
	local dirz = (c - split).unit
	local dirx = diry:Cross(dirz).unit

	local posA = split + diry*yA/2 - dirz*zA/2
	local posB = split + diry*yB/2 + dirz*zB/2

	local partA = spawnTrianglePart(ad[1],ad[2])
	partA.Name = "TrianglePart"
	partA.Size = Vector3.new(xA,math.min(yA,2048),math.min(zA,2048))
	local mA = Instance.new("SpecialMesh",partA)
	mA.MeshType = Enum.MeshType.Wedge
	mA.Scale = Vector3.new(xA,yA,zA)/partA.Size
	mA.Offset = Vector3.new(-n*(partA.Size.x-xA)/2,0,0)
	if mA.Scale == Vector3.new(1,1,1) then mA:Destroy() end
	partA.CFrame = CFrame.new(posA.x,posA.y,posA.z, dirx.x,diry.x,dirz.x, dirx.y,diry.y,dirz.y, dirx.z,diry.z,dirz.z)
	partA.CFrame = partA.CFrame:toWorldSpace(CFrame.new(n*math.max(.2,xA)/2,0,0))
	dirx = dirx * -1
	dirz = dirz * -1

	local partB = spawnTrianglePart(ad[1],ad[2])
	partB.Name = "TrianglePart"
	partB.Size = Vector3.new(xB,yB,zB)
	local mB = Instance.new("SpecialMesh",partB)
	mB.MeshType = Enum.MeshType.Wedge
	mB.Scale = Vector3.new(xB,math.min(yB,2048),math.min(zB,2048))/partB.Size
	mB.Offset = Vector3.new(n*(partB.Size.x-xB)/2,0,0)
	if mB.Scale == Vector3.new(1,1,1) then mB:Destroy() end
	partB.CFrame = CFrame.new(posB.x,posB.y,posB.z, dirx.x,diry.x,dirz.x, dirx.y,diry.y,dirz.y, dirx.z,diry.z,dirz.z)
	partB.CFrame = partB.CFrame:toWorldSpace(CFrame.new(-n*math.max(.2,xB)/2,0,0))
	
	return partA,partB
end

local function CreateTri()
	local Target = Mouse.Target
	if (Target ~= nil and Target.Locked == false and not Target:IsA("WedgePart")) then
		local Icheck = true
		for i,v in next,Points do
			if (v[1] == Target) then 
				Icheck = false 
				break 
			end
		end
		if (Icheck) then
			table.insert(Points,{Target,Target.Position})
			if (#Points >= 3) then
				local Pts = {{Points[1][1],Points[1][2]},{Points[2][1],Points[2][2]},{Points[3][1],Points[3][2]}}
				local Data = {Color,Material,Thickness}
				local Check = true
				for i,v in next,Tris do
					local Chcked1 = Pts[1][1] == v[2][1] or Pts[1][1] ==v [3][1] or Pts[1][1] == v[4][1]
					local Chcked2 = Pts[2][1] == v[2][1] or Pts[2][1] ==v [3][1] or Pts[2][1] == v[4][1]
					local Chcked3 = Pts[3][1] == v[2][1] or Pts[3][1] ==v [3][1] or Pts[3][1] == v[4][1]
					if (Chcked1 and Chcked2 and Chcked3) then
						for _,a in pairs(v[1]) do
							a:Destroy()
						end
						for _,a in pairs(v[5]) do
							a:disconnect()
						end
						table.remove(Tris,i)
						break
					end
				end			
				local N =- 1
				
				if (Align == "Center") then 
					N = 0 
				elseif (Align == "Inverted") then 
					N = 1 
				end
				local nTris={}
				
				nTris[1],nTris[2]=drawTriangle(Points[1][2],Points[2][2],Pts[3][2],N,Data)
				local nFunc={}
				table.insert(Tris,{nTris,Pts[1],Pts[2],Pts[3],nFunc,Data})
				for i=1,3 do
					table.insert(nFunc,Points[i][1].Changed:connect(function(property)
						if (property=="Position") then
							Pts[i][2] = Pts[i][1].Position
							for i,v in next,nTris do
								v:Destroy()
							end
							nTris[1],nTris[2]=drawTriangle(Pts[1][2],Pts[2][2],Pts[3][2],N,Data)
						end
					end))
				end
				Points={}
			end
		end
	end
end

Mouse.Button1Down:connect(CreateTri)

Change Align to one of this
image Center or Inversed

11 Likes

Look up “how to make a triangle between three points” iirc

1 Like

Thanks for your help!
I’ve implemented your code with my current building system as shown below:
https://gyazo.com/db9e7b3378a47ff8868f38a2529134c2.gif

I am assuming that the align variable is there to assign the direction of the triangle to be drawn, because when i change the variable it allows me to draw triangles facing the other way:
https://gyazo.com/b71c408197fc75139d44e7dcc499bc7c.gif

Could there be any way for the alignment of a triangle to be detected via the script so the variable doesn’t have to be changed manually every time?

1 Like

No, there is no way.

Also could you make the script as solution :slightly_smiling_face::sweat_smile:.

Edit:
I mean there is no way to detect it from the script i gave you.

1 Like

Done.
Thanks for your help!

I will take a good look at the script you gave me to see how it works so maybe I can find a way to detect the alignment needed because it is kind of essential for my game

2 Likes

Is this able to work with more than 3 points?

What do you mean?
It connects 3 parts together.
Want video?

I saw from his gif that it was working when you place 3 points. But in the video he provided in his question, that video shows the person placing 4 points, and the shape being created from that.

No there is not but you can do it I think let me check the script.

image

I’m not on my comp so i can’t really do any looking myself, but ye was just curious. Cause I asked a sinilar question to this about a week ago and got no responses for it. I was looking for something like the video he linked

Which if you skip to where they place floors, they place 4 points before the floor is created. I’ve looked into like point set triangulation and all that but ye

I will record a video then for you.

Its possible but need to code a lot.

It is not like changing variable I did not made it like that if you want it to work like that I don’t suggest my script but use it as a template how to make it.

With a bit of rewriting in the code, I managed to create the floor building system that I was looking for!
https://gyazo.com/92c18dca08bdc913548c5f83e6b0b288.gif

8 Likes

Hey there! What you’ve made looks very cool, and if you don’t intend for this code to work for any more than four points, please just tell me to move along haha. If you want to use more than 4 bullet points and generate a complex shape, there’s a technique in 3D Graphics called Polygon Triangulation.

It’ll allow you to generate points for more complex structures, if indeed that’s what you’re after. If it is something you’re interested in, lmk and I’d be happy to assist. Otherwise, good luck developing. :smiley:

1 Like

Already figured it out :stuck_out_tongue_winking_eye:
https://gyazo.com/b10d40f7e18bcab62fedfbb3ac35cf36

9 Likes