Best way to do infinite corridor

Hi,

So far, I have created a function which generates a model (corridor) and depending on the value in the function parameters, either attaches it on the front of the existing corridor piece or the back piece.

The idea is to have an infinite corridor which goes both ways (forwards and backwards), and I was wondering what the best way would be to do this (it only needs to render the corridors locally).

For detecting what corridor the player is in, I have tried using the Touched event on the players foot or on their leg if its an R6 rig. Even though it works, I’m not entirely sure if that’s the most optimal method to use.

For telling the game where to generate the corridors, so far I have tried using :Dot on the players head front vector and the corridors wall front vector (the game is first person only). I have also tried using the magnitude the player is away from the front of the corridor to determine whether they are at the front of the corridor, or the back of the corridor.

For the deletion of the corridors, I was thinking of using a for loop to gather all corridor segments and use magnitude on a part to detect the distance, then do ‘if magnitude > (insert distance here) then’ to remove segments which are far away.

I am wondering what would be the best ways to:

  1. detect which corridor segment the player is in
  2. what method I should use to tell where the corridor should generate (e.g front or back)
  3. what the indication should be to delete the corridor segments

Here’s what I have so far as a base:

local char = script.Parent
local plr = game.Players.LocalPlayer

local head = char.Head

local scpspawns = 0

local area = workspace['479']


local function new479(area,front)
	local clone = area:Clone()
	local floor = area.floor
	local fsize = floor.Size

	clone.Parent = workspace
	scpspawns = scpspawns + 1
	if front == true then
		clone:SetPrimaryPartCFrame(clone.floor.CFrame * CFrame.new(0,0,fsize.Z) ) -- add to front

	else 
		clone:SetPrimaryPartCFrame(clone.floor.CFrame * CFrame.new(0,0,-fsize.Z) ) -- add to back
	end
	
	return clone
end

I feel like I’m probably overcomplicating it due to there being so many different ways to do it, so please leave suggestions on how to approach this, or if there’s anything that I should change in the scripts current stage.

If you’d like me to clarify anything please reply with your question and I will answer it.

Thanks :slight_smile:

local multiT = 1
multiT += 1 --use in the loop, it will double per trigger

above will act as some sort of multiplying number

(clone.floor.CFrame * CFrame.new(0,0,fsize.Z*multiT) ) --will work

and this one will increase the distance between intervals

1 Like

Hey, thanks for the fast response, I already scripted the intervals the corridor needs to travel in the function.
I’m looking for the most optimal ways to detect which segment the character is in, on what side of the corridor the character is on and the deletion of corridors which are a long distance away to prevent any lag. I included the things I have tried already in my starting post (I think its called?), I understand its probably quite difficult to read due to the length of it lol.

Thank you for the help anyway though :slight_smile:

i’m pretty sure you can use Region3.news to indicate wherever side they are on with some adjusting

1 Like

Most likely, I’ll quickly try that out and see how it goes, thanks again

so you first need 2 seeds so that all clients generate the same corridor

then you use Random | Roblox Creator Documentation with the 2 seeds to select the correct model for the corridor segment

then we use pivotTo to pivot the model onto the previous models end part

here is a video


here is a demo project
infinite corridor.rbxl (37.6 KB)


this is the script inside the project

if game:IsLoaded() == false then game.Loaded:Wait() end
local replicatedStorage = game:GetService("ReplicatedStorage")
local runService = game:GetService("RunService")

local part1 = workspace.Start1
local part2 = workspace.Start2
local random1 = Random.new(replicatedStorage.Seed1.Value)
local random2 = Random.new(replicatedStorage.Seed2.Value)
local models = {}
local loadDistance = 256

for i, child in replicatedStorage.Models:GetChildren() do
	models[tonumber(child.Name)] = child
end

runService.Heartbeat:Connect(function()
	local character = game.Players.LocalPlayer.Character
	if character == nil then return end
	local position = character:GetPivot().Position
	
	local magnitude1 = (part1.Position - position).Magnitude
	if magnitude1 < loadDistance then
		local r = random1:NextInteger(1, #models)
		local clone = models[r]:Clone()
		clone:PivotTo(part1.CFrame)
		clone.Parent = workspace
		part1 = clone.End
	end
	
	local magnitude2 = (part2.Position - position).Magnitude
	if magnitude2 < loadDistance then
		local r = random2:NextInteger(1, #models)
		local clone = models[r]:Clone()
		clone:PivotTo(part2.CFrame)
		clone.Parent = workspace
		part2 = clone.End
	end
end)

and this is what it looks like

2 Likes