You can write your topic however you want, but you need to answer these questions:
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.
What is the issue? Include screenshots / videos if possible! I have no idea where to start.
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:
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.
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
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
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.