I’m in the midst of coding something that’s meant to use parts to generate a loop. It works for the most part but requires some adjustments that I’m unsure how to fix. These are the results of both attempts:
I’d like for those parts to be inline just like the rest of them. I did manage to make one that did keep them inline… but the whole loop itself was slanted.
As you could imagine, this is not the result that I’m looking for, and I myself am not particularly math savvy. What would it take to fix this?
Here’s the generation code for reference:
Generation Code (1st attempt)
--Po1 and Po2 are the start and end positions (chosen outside of the function).
--Code is just a custom module script for making some functions more convenient.
--There are other variables outside of this function; feel free to ignore those.
function DisplayLoop() if not Po1 or not Po2 then return end
local Radius,LoopWidth,Segments = (Po1-Po2).Magnitude,5,24
local CenterCF = (CFrame.new(Po1,Po2):ToWorldSpace(CFrame.new(-LoopWidth,0,-Radius))).Position
CenterCF = CFrame.new(Po1,CenterCF):ToWorldSpace(CFrame.new(0,Radius,0))
--Set up loop points
local GetLoopPoints = {}
for N = 1,Segments,1 do
local Rad = math.rad((360*N)/Segments)
local NewPoint = (CenterCF*CFrame.fromEulerAnglesXYZ(Rad,0,0)):ToWorldSpace(CFrame.new((N/Segments)*5,-Radius,0)).Position
table.insert(GetLoopPoints,NewPoint)
end
local ParentTo = Code.new"Model"{Name="Loop",Parent=workspace}
--Make the rail connecting the initial and starting point of the loop
local NewMag = (Po1-GetLoopPoints[1]).Magnitude
local NewC = CFrame.new(Po1,GetLoopPoints[1]):ToWorldSpace(CFrame.new(0,0,NewMag/-2))
local StartRail = Code.new"Part"{Name=NewName,Parent=ParentTo,Material=Material,Color=PartColor,Anchored=true,
CanCollide=CanCollide,CFrame = NewC,Size = Vector3.new(Width,Height,NewMag)}
Code.ChangeSame(Enum.SurfaceType.SmoothNoOutlines,StartRail){
"BackSurface","BottomSurface","FrontSurface","LeftSurface","RightSurface","TopSurface"}
--Start making the actual loop
local Len = (GetLoopPoints[1]-GetLoopPoints[2]).Magnitude
for N,P in pairs(GetLoopPoints) do
local IsFinal = not (N<#GetLoopPoints)
local NewLen = (GetLoopPoints[N]-Po2).Magnitude
local NewCF = not IsFinal and CFrame.new(GetLoopPoints[N],GetLoopPoints[N+1]):ToWorldSpace(CFrame.new(0,0,Len/-2))
or CFrame.new(GetLoopPoints[N],Po2):ToWorldSpace(CFrame.new(0,0,NewLen/-2))
local NewSize = not IsFinal and Vector3.new(Width,Height,Len) or Vector3.new(Width,Height,NewLen)
local Rail = Code.new"Part"{Name=(NewName .. tostring(N)),Parent=ParentTo,Material=Material,Color=PartColor,
Anchored=true,CanCollide=CanCollide,CFrame = NewCF,Size = NewSize}
Code.ChangeSame(Enum.SurfaceType.SmoothNoOutlines,Rail){
"BackSurface","BottomSurface","FrontSurface","LeftSurface","RightSurface","TopSurface"}
end
--End the process
SwitchMode(M1)
end
Generation Code (2nd attempt)
--Po1 and Po2 in this case is simply trying to make a loop from the
--facing-front position of the selected part instead of trying to link
--1 end to another perfectly. The connection will occur after the loop is made
--(not shown in this example).
--Variables
local Po1,Po2 = workspace.PointA.Position,workspace.PointA.CFrame:ToWorldSpace(CFrame.new(0,0,-1)).Position
local Code = require(script.Code)
local NewName,CanCollide,Material,PartColor = "Rail",true,Enum.Material.SmoothPlastic,BrickColor.palette(123).Color
local Width,Height = 0.5,2
local Segments,Radius,LoopWidth = 20,10,8
--Make the initial rail:
local ParentTo = Code.new"Model"{Name="Loop",Parent=workspace}
local NewC = CFrame.new(Po1,Po2):ToWorldSpace(CFrame.new(0,0,Radius/-2))
local StartRail = Code.new"Part"{Name=NewName,Parent=ParentTo,Material=Material,Color=PartColor,Anchored=true,
CanCollide=CanCollide,CFrame = NewC,Size = Vector3.new(Width,Height,Radius)}
--Do stuff:
local Rails,Angle,Prev = {},360/Segments,StartRail
for N = 1,Segments-2,1 do
local NewCF = Prev.CFrame:ToWorldSpace(CFrame.new(0,0,Radius/-2))
NewCF = NewCF*CFrame.fromEulerAnglesXYZ(math.rad(Angle),math.rad(LoopWidth),0)
NewCF = NewCF:ToWorldSpace(CFrame.new(0,0,Radius/-2))
local NewSize = Vector3.new(Width,Height,Radius)
Prev = Code.new"Part"{Name=(NewName .. tostring(N)),Parent=ParentTo,Material=Material,Color=PartColor,
Anchored=true,CanCollide=CanCollide,CFrame = NewCF,Size = NewSize}
table.insert(Rails,Prev)
end
--Make the final rail:
NewC = Prev.CFrame:ToWorldSpace(CFrame.new(0,0,Radius/-2))
local NewDist = (NewC.Position-Po2).Magnitude
NewC = CFrame.new(NewC.Position,Po2):ToWorldSpace(CFrame.new(0,0,NewDist/-2))
Code.new"Part"{Name=NewName,Parent=ParentTo,Material=Material,Color=PartColor,Anchored=true,
CanCollide=CanCollide,CFrame = NewC,Size = Vector3.new(Width,Height,NewDist)}
--Quick final adjustment:
Code.ChangeSame(Enum.SurfaceType.SmoothNoOutlines,unpack(ParentTo:GetChildren())){
"BackSurface","BottomSurface","FrontSurface","LeftSurface","RightSurface","TopSurface"}
Explaining some variables just in case:
• Radius: How tall/wide it should be.
• LoopWidth: How far it should go from left-to-right or vice-versa.
• Segments: How many individual parts it takes to make it.
I’ve tried looking around the forums already and haven’t found a similar issue. If there is one and this ends up being a repost of some sort, I apologize.