Parallax Portal script with collection service and distance based load-off

Hi, I updated the Parallax Portal script that adds two simple useful features

  1. I added collection service (Be able to insert multiple portals without duplicating the scripts)
  2. I added distance based load-off (The portal(s) will stop updating when the camera is too far)

The load-off only stops the script from calculating each frame and does not disconnect the function

LocalScript:

--!strict

local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local Player = game:GetService("Players").LocalPlayer

local loadDistance = 40 -- Distance at which the portal will stop working

local CollectionService = game:GetService("CollectionService")
local GetTagged = CollectionService:GetTagged("ParallaxPortal") -- Remember to tag the portals with "ParallaxPortal" or something else

local function update(portal:BasePart, layers)
	local camera = Workspace.CurrentCamera :: Camera

	local portalRatio = portal.Size.Y / portal.Size.X
	local cameraDirection = (portal.Position - camera.CFrame.Position).Unit
	local portalDirection = portal.CFrame:VectorToObjectSpace(cameraDirection)
	local correctedDirection = Vector3.new(portalDirection.X, portalDirection.Y / portalRatio, 0)

	for layer, info in layers do
		local offset = UDim2.fromScale(correctedDirection.X * info.depth, correctedDirection.Y * info.depth)
		layer.Position = info.position + offset
	end
end

local function initialize(portal, portalGui)
	type LayerInfo = { position: UDim2, depth: number }

	local layers: { [GuiObject]: LayerInfo } = {}

	local function addLayer(layer: any)
		if not layer:IsA("GuiObject") then
			return
		end

		layers[layer] = {
			position = layer.Position,
			depth = layer:GetAttribute("ParallaxDepth") or 0,
		}
	end
	
	portalGui.ChildAdded:Connect(addLayer)
	RunService.RenderStepped:Connect(function()
		if (workspace.CurrentCamera.CFrame.Position-portal.Position).Magnitude <= loadDistance then -- Stop updating the portal at the load distance
			update(portal, layers)
		end
	end)

	for _, layer in portalGui:GetChildren() do
		addLayer(layer)
	end
end

for _,p in pairs(GetTagged) do -- Initialize each portal that is tagged
	initialize(p.Portal, p.Portal.PortalGui.Portal)
end

How to use:

Simply insert the model/script and tag each portal with the ParallaxPortal tag

Get the original model here:

Download the updated model here:

Parallax Portal - Updated.rbxm (14.4 KB)

Please comment bellow if there are any issues. I will try to fix them and update this post


The original model was not created by me

6 Likes