This topic is really old and I remember when it first was posted.
But this is a ModuleScript that I used for making a Roundabout that you would see at a Playground
It should give you a general idea of how to make it.
Only works on LocalScripts.
local module = {}
local Collection = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local Map = workspace:WaitForChild("Map")
local Infrastructure = Map:WaitForChild("Infrastructure")
local Folder = Infrastructure:WaitForChild("Roundabouts")
local Camera = workspace.CurrentCamera
local Ignore = {}
local function ExitRoundabout(Roundabout)
warn("Exited")
end
local function EnterRoundabout(Roundabout)
warn("Entered")
end
local CFrameSpinners = {}
local Roundabouts = {}
function module.Init()
local DownVector = Vector3.new(0, -1, 0)
local newRay = Ray.new
local FindPartOnRay = workspace.FindPartOnRay
local FindPartOnRayWithIgnoreList = workspace.FindPartOnRayWithIgnoreList
local function fpor(start, direction, distance, IgnoreModel, WhitelistFolder)
local attempt = 0
local hit, pos, origin, material = nil, start, -direction, nil
while distance > 0 and attempt < 10 do
local ray = newRay(start, direction * distance)
hit, pos, origin, material = FindPartOnRay(workspace, ray, IgnoreModel, false, true)
local d = (start - pos).Magnitude
if hit and (hit:IsDescendantOf(WhitelistFolder) or hit.CanCollide) then
return hit, pos, origin, material
end
start = pos
distance = distance - d
attempt = attempt + 1
end
return hit, pos, origin, material
end
local LastRoundabout
local lt = tick()
local function Heartbeat()
local t = tick()
local dt = t - lt
lt = t
local RoundaboutModel, Spinner, SpinnerCf, RootPart
local Character = LocalPlayer.Character
if Character then
local Humanoid = Character:FindFirstChild("Humanoid")
if Humanoid then
RootPart = Humanoid.RootPart
if RootPart then
RoundaboutModel = fpor(RootPart.Position, DownVector, 10, Character, Folder)
if RoundaboutModel and not RoundaboutModel:IsDescendantOf(Folder) then
RoundaboutModel = nil
end
end
end
end
if not RoundaboutModel then
if LastRoundabout then
ExitRoundabout(LastRoundabout)--Exited LastRoundabout
end
LastRoundabout = nil
end
local ClosestDist, ClosestRoundabout = 500, nil
for i,Roundabout in pairs(Roundabouts) do
local TSpinner = Roundabout:FindFirstChild("Spinner")
if RootPart then
if TSpinner then
local Dist = (RootPart.Position - TSpinner.Position).Magnitude
if ClosestDist >= Dist then
ClosestDist = Dist
ClosestRoundabout = Roundabout
end
if CFrameSpinners[TSpinner] == nil then
CFrameSpinners[TSpinner] = TSpinner.CFrame
end
end
end
if RoundaboutModel and RoundaboutModel:IsDescendantOf(Roundabout) then
Spinner = TSpinner
SpinnerCf = CFrameSpinners[TSpinner]
if not LastRoundabout then
EnterRoundabout(Roundabout)--Entered
elseif LastRoundabout ~= Roundabout then
ExitRoundabout(LastRoundabout)--Exited LastRoundabout
EnterRoundabout(Roundabout)--Entered Roundabout
end
LastRoundabout = Roundabout
else
CFrameSpinners[TSpinner] = TSpinner.CFrame
end
end
if Spinner then
local NewCF = Spinner.CFrame
if CFrameSpinners[Spinner] == nil then
CFrameSpinners[Spinner] = NewCF
end
SpinnerCf = CFrameSpinners[Spinner]
local Relative = NewCF * SpinnerCf:Inverse()
RootPart.CFrame = Relative * RootPart.CFrame
local CamRel = Camera.CFrame:ToObjectSpace(Camera.Focus)
Camera.CFrame = Camera.CFrame * CamRel * (Relative - Relative.p) * CamRel:Inverse()
CFrameSpinners[Spinner] = Spinner.CFrame
end
end
RunService.Heartbeat:Connect(Heartbeat)
local function RoundaboutAdded(Model)
table.insert(Roundabouts,Model)
end
local function RoundaboutRemoved(Model)
for index,value in pairs(Roundabouts) do
if value == Model then
table.remove(Roundabouts,index)
end
end
end
for _, Model in next, Collection:GetTagged("Roundabout") do
RoundaboutAdded(Model)
end
Collection:GetInstanceAddedSignal("Roundabout"):Connect(RoundaboutAdded)
Collection:GetInstanceRemovedSignal("Roundabout"):Connect(RoundaboutRemoved)
end
return module