Pipe building system

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    A pipe building system that connects the pipes automatically so you don’t have the problem of too long or too short.

  2. What is the issue? Include screenshots / videos if possible!
    I have no idea where to start.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    Countless hours of research, i kind of understand but still i would have no idea how to do it myself.

I hope you guys understand what i need, and help me. i just have no idea where to start.
These are the pipes i would like to use:

`
Edit: Replying to everyone: your ideas are great and would definitely work, the problem is just that… how? how would i script these sorta things?

1 Like

I can’t help you much, but a start would possibly be making a path of just points or whatever, from the start, to the goal. It might be a bit hard with all of the different sizes, but if the sizes are aligned to a grid it would work pretty well i believe. You can use roblox built in pathfinding service or possible find anyone else’s on the devforum.

One thing you can do is to define connection points, like point A for inlet and B for outlet, then you just do something like lego, connect points B on point A from another pipe. I would recommend you to use a part, then you just need to set the CFrame.

You’ll likely need a gridlocked placing system.

Thank you all very much for the feedback so far, ive been doing even more research, and ive been trying to detect if the player can see A-inlet and it will then snap to that. But, i cant seem to raycast correctly from the head. this is what i have now, dont bully my code.

local camera = workspace.CurrentCamera
local worldPoint = Vector3.new(0, 10, 0)
local vector, inViewport = camera:WorldToViewportPoint(worldPoint)

local viewportPoint = Vector2.new(vector.X, vector.Y)
local depth = vector.Z



local part = workspace.CurrentCamera

local origin = part.CFrame

local direction = part.CFrame.LookVector

local raycastResult = workspace:Raycast(origin, direction)

if raycastResult then
	print(raycastResult.Position)
	print(raycastResult.Name)
end

Wouldn’t need a raycast for a grid based building system.

Like i said before, im not trying to build a grid based at the moment. i want to be able to have the pipes connect automatically, and i have some basic pipes set in place so a grid might not be needed.

Ok so your probably going to want to know where the player clicked in a Vector3 value. You get this using game.Players.LocalPlayer:GetMouse().Hit.p However I would recommend braking this down into:

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()

if mouse.MouseButton1Down:Connect(function()
    print(mouse.Hit.p)
end)

The above code will print a Vector3 value. Once you have the Vector3 value you can place you model to this location using:

local StraightPipe = game.ServerStorage.StraightPipe
local pipe = StraightPipe:Clone()
pipe.Parent = game.Workspace
pipe.Position = mouse.Hit.p

If you want to make a grid system (most likely) you should simply round the Vecor3 value to the nearest whole number Rounding Number to Nearest Whole

I hope this will be able to get you started.

1 Like

It really depends on the type and size of your pipes. If you want your pipes to be all the same size then a grid system would definitely be the easiest method.

A method I used for a building game was to have a raycast then push the object away relative to the CFrame of the Object. This allows for a building system to be able to snap even when it isn’t aligned perfectly straight.

You will have to adapt the code I used for yourself because the code I used works for objects that are exactly the same size.

-- You need a reference CFrame and a "snap" location. In this instance I the snap location can be found simply by rounding the position of the mouse to the closest grid size
local function RoundToNearest(number: number, roundTo: number): number -- Handy function to remember
	local x = number + (roundTo / 2)
	return x - (x % roundTo)
end
-- To do this convert mouse position to target object space then round to the object space and then reconvert back to world space
local Target = RaycastResult.Position + RaycastResult.Normal -- We do this to avoid edge cases where surface of part is boundary
local BasePart: BasePart = RaycastResult.Instance -- This will be our reference.(I am raycasting from camera to mouse for this)
Target = BasePart.CFrame:PointToObjectSpace(Target)
Target = Vector3.new(
	RoundToNearest(Target.X,4),
	RoundToNearest(Target.Y,4),
	RoundToNearest(Target.Z,4)						
)					
Target = BasePart.CFrame:ToWorldSpace(CFrame.new(Target))
Preview.CFrame = Target

Another option you have is to use attachments and the method SetPrimaryPartCFrame and position your models using that. I won’t go into detail but it is much easier to do.